File Coverage

blib/lib/BACnet/PDUTypes/ConfirmedRequest.pm
Criterion Covered Total %
statement 65 77 84.4
branch 6 12 50.0
condition n/a
subroutine 15 16 93.7
pod 0 6 0.0
total 86 111 77.4


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2              
3             package BACnet::PDUTypes::ConfirmedRequest;
4              
5 27     27   5877172 use warnings;
  27         53  
  27         1493  
6 27     27   163 use strict;
  27         50  
  27         642  
7              
8 27     27   114 use bytes;
  27         46  
  27         146  
9              
10 27     27   13242 use BACnet::APDU;
  27         105  
  27         962  
11 27     27   168 use BACnet::DataTypes::SequenceValue;
  27         48  
  27         643  
12              
13 27     27   12591 use BACnet::ServiceRequestSequences::COVConfirmedNotification;
  27         85  
  27         974  
14 27     27   193 use BACnet::ServiceRequestSequences::COVUnconfirmedNotification;
  27         51  
  27         478  
15 27     27   114 use BACnet::ServiceRequestSequences::ReadProperty;
  27         48  
  27         623  
16 27     27   113 use BACnet::ServiceRequestSequences::SubscribeCOV;
  27         47  
  27         937  
17              
18             require BACnet::PDUTypes::Utils;
19              
20 27     27   131 use parent 'BACnet::PDUTypes::PDU';
  27         46  
  27         197  
21              
22             our $service_choice_service_request_skeleton =
23             { 1 =>
24             $BACnet::ServiceRequestSequences::COVConfirmedNotification::request_skeleton,
25             };
26              
27             sub construct {
28 3     3 0 15853 my ( $class, @rest ) = @_;
29              
30 3         19 my %args = (
31             invoke_id => undef,
32             service_choice => undef,
33             service_request => undef,
34             flags => 0x00,
35             @rest,
36             );
37              
38             my $self = {
39             data => '',
40             invoke_id => $args{invoke_id},
41             service_choice => $args{service_choice},
42             service_request => $args{service_request},
43             flags => $args{flags},
44 3         26 max_resp => BACnet::APDU::MAX_RESPONSE(),
45             };
46              
47             $self->{data} .= pack( 'C',
48             ( $BACnet::APDU::apdu_types->{'Confirmed-Request'} << 4 ) |
49 3         30 $self->{flags} );
50              
51 3         9 $self->{data} .= pack( 'C', BACnet::APDU::MAX_RESPONSE() );
52              
53 3         11 $self->{data} .= pack( 'C', $args{invoke_id} );
54              
55             $self->{data} .= pack(
56             'C',
57             $BACnet::PDUTypes::Utils::confirmed_service->{
58             $self->{service_choice}
59             }
60 3         14 );
61              
62 3         28 $self->{data} .= $self->{service_request}->data();
63              
64 3         18 return bless $self, $class;
65              
66             #flags are 0000
67              
68             }
69              
70             sub parse {
71              
72 3     3 0 10 my ( $class, $data_in, $skeleton ) = @_;
73              
74 3         11 my $self = bless { data => $data_in, }, $class;
75              
76 3 50       18 if ( length($data_in) < 4 ) {
77 0         0 $self->{error} = "Confirmed request: too short";
78 0         0 return $self;
79             }
80              
81 3         7 my $offset = 0;
82              
83 3         20 $self->{flags} = unpack( 'C', substr( $data_in, $offset, 1 ) ) & 0x0f;
84              
85 3 50       14 if ( ( $self->{flags} & 0x08 ) != 0 ) {
86 0         0 $self->{error} = "Confirmed request: segmented message";
87 0         0 return $self;
88             }
89              
90 3         9 $offset += 1;
91              
92 3         12 $self->{max_resp} = unpack( 'C', substr( $data_in, $offset, 1 ) ) & 0x0f;
93              
94             #in case of adding segmentation add here
95 3         7 $offset += 1;
96              
97 3         14 $self->{invoke_id} = unpack( 'C', substr( $data_in, $offset, 1 ) );
98 3         6 $offset += 1;
99              
100             my $service_choice = $BACnet::PDUTypes::Utils::confirmed_service_rev->{
101 3         19 unpack( 'C', substr( $data_in, $offset, 1 ) ) };
102              
103 3 50       12 if ( !defined $service_choice ) {
104 0         0 $self->{error} = "Confirmed request: unknown service choice";
105 0         0 return $self;
106             }
107              
108 3         11 $self->{service_choice} = $service_choice;
109 3         6 $offset += 1;
110              
111 3 50       10 if ( !defined $skeleton ) {
112             $skeleton = $service_choice_service_request_skeleton->{
113             $BACnet::PDUTypes::Utils::confirmed_service->{
114             $self->{service_choice}
115             }
116 0         0 };
117             }
118              
119 3 50       10 if ( !defined $skeleton ) {
120 0         0 $self->{error} = "Confirmed request: unknown service choice";
121 0         0 return $self;
122             }
123              
124             $self->{service_request} =
125 3         49 BACnet::DataTypes::SequenceValue->parse( substr( $data_in, $offset ),
126             $skeleton );
127              
128 3 50       14 if ( defined $self->{service_request}->{error} ) {
129 0         0 $self->{error} = "Confirmed request: error in service request";
130             }
131 3         12 return $self;
132             }
133              
134             sub service_choice {
135 6     6 0 9156 my ($self) = @_;
136              
137 6         66 return $self->{service_choice};
138             }
139              
140             sub service_request {
141 6     6 0 16 my ($self) = @_;
142              
143 6         21 return $self->{service_request};
144             }
145              
146             sub invoke_id {
147 6     6 0 16 my ($self) = @_;
148              
149 6         20 return $self->{invoke_id};
150             }
151              
152             sub max_resp {
153 0     0 0   my ($self) = @_;
154              
155 0           return $self->{max_resp};
156             }
157             1;