File Coverage

blib/lib/BACnet/APDU.pm
Criterion Covered Total %
statement 42 62 67.7
branch 0 6 0.0
condition n/a
subroutine 14 16 87.5
pod 0 2 0.0
total 56 86 65.1


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;