/src/wireshark/epan/dissectors/packet-bacapp.c
Line | Count | Source |
1 | | /* packet-bacapp.c |
2 | | * Routines for BACnet (APDU) dissection |
3 | | * Copyright 2001, Hartmut Mueller <hartmut[AT]abmlinux.org>, FH Dortmund |
4 | | * Enhanced by Steve Karg, 2005, <skarg[AT]users.sourceforge.net>, Atlanta |
5 | | * Enhanced by Herbert Lischka, 2005, <lischka[AT]kieback-peter.de>, Berlin |
6 | | * Enhanced by Felix Kraemer, 2010, <sauter-cumulus[AT]de.sauter-bc.com>, |
7 | | * Sauter-Cumulus GmbH, Freiburg |
8 | | * |
9 | | * Wireshark - Network traffic analyzer |
10 | | * By Gerald Combs <gerald[AT]wireshark.org> |
11 | | * Copyright 1998 Gerald Combs |
12 | | * |
13 | | * SPDX-License-Identifier: GPL-2.0-or-later |
14 | | */ |
15 | | |
16 | | #include "config.h" |
17 | | |
18 | | #include <epan/packet.h> |
19 | | #include <epan/to_str.h> |
20 | | #include <epan/strutil.h> |
21 | | #include <epan/reassemble.h> |
22 | | #include <epan/expert.h> |
23 | | #include <epan/proto_data.h> |
24 | | #include <epan/tfs.h> |
25 | | #include <epan/stats_tree.h> |
26 | | #include "packet-bacapp.h" |
27 | | |
28 | | static int bacapp_tap; |
29 | | |
30 | | /* formerly bacapp.h contains definitions and forward declarations */ |
31 | | |
32 | | /* BACnet PDU Types */ |
33 | 14.4k | #define BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST 0 |
34 | 1.32k | #define BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST 1 |
35 | 94 | #define BACAPP_TYPE_SIMPLE_ACK 2 |
36 | 1.30k | #define BACAPP_TYPE_COMPLEX_ACK 3 |
37 | 52 | #define BACAPP_TYPE_SEGMENT_ACK 4 |
38 | 688 | #define BACAPP_TYPE_ERROR 5 |
39 | 44 | #define BACAPP_TYPE_REJECT 6 |
40 | 144 | #define BACAPP_TYPE_ABORT 7 |
41 | | #define MAX_BACAPP_TYPE 8 |
42 | | |
43 | 7.94k | #define BACAPP_SEGMENTED_REQUEST 0x08 |
44 | 275 | #define BACAPP_MORE_SEGMENTS 0x04 |
45 | | #define BACAPP_SEGMENTED_RESPONSE 0x02 |
46 | | #define BACAPP_SEGMENT_NAK 0x02 |
47 | | #define BACAPP_SENT_BY 0x01 |
48 | | |
49 | | /** |
50 | | * dissect_bacapp ::= CHOICE { |
51 | | * confirmed-request-PDU [0] BACnet-Confirmed-Request-PDU, |
52 | | * unconfirmed-request-PDU [1] BACnet-Unconfirmed-Request-PDU, |
53 | | * simpleACK-PDU [2] BACnet-SimpleACK-PDU, |
54 | | * complexACK-PDU [3] BACnet-ComplexACK-PDU, |
55 | | * segmentACK-PDU [4] BACnet-SegmentACK-PDU, |
56 | | * error-PDU [5] BACnet-Error-PDU, |
57 | | * reject-PDU [6] BACnet-Reject-PDU, |
58 | | * abort-PDU [7] BACnet-Abort-PDU |
59 | | * } |
60 | | * @param tvb the tv buffer of the current data |
61 | | * @param pinfo the packet info of the current data |
62 | | * @param tree the tree to append this item to |
63 | | **/ |
64 | | |
65 | | /** |
66 | | * ConfirmedRequest-PDU ::= SEQUENCE { |
67 | | * pdu-type [0] Unsigned (0..15), -- 0 for this PDU Type |
68 | | * segmentedMessage [1] BOOLEAN, |
69 | | * moreFollows [2] BOOLEAN, |
70 | | * segmented-response-accepted [3] BOOLEAN, |
71 | | * reserved [4] Unsigned (0..3), -- must be set zero |
72 | | * max-segments-accepted [5] Unsigned (0..7), -- as per 20.1.2.4 |
73 | | * max-APDU-length-accepted [5] Unsigned (0..15), -- as per 20.1.2.5 |
74 | | * invokeID [6] Unsigned (0..255), |
75 | | * sequence-number [7] Unsigned (0..255) OPTIONAL, -- only if segmented msg |
76 | | * proposed-window-size [8] Unsigned (0..127) OPTIONAL, -- only if segmented msg |
77 | | * service-choice [9] BACnetConfirmedServiceChoice, |
78 | | * service-request [10] BACnet-Confirmed-Service-Request OPTIONAL |
79 | | * } |
80 | | * @param tvb the tv buffer of the current data |
81 | | * @param pinfo the packet info of the current data |
82 | | * @param tree the tree to append this item to |
83 | | * @param offset the offset in the tvb |
84 | | * @return modified offset |
85 | | */ |
86 | | static unsigned |
87 | | fConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
88 | | |
89 | | /** |
90 | | * @param tvb the tv buffer of the current data |
91 | | * @param pinfo the packet info of the current data |
92 | | * @param tree the tree to append this item to |
93 | | * @param offset the offset in the tvb |
94 | | * @param ack - indicates whether working on request or ack |
95 | | * @param svc - output variable to return service choice |
96 | | * @param tt - output varable to return service choice item |
97 | | * @return modified offset |
98 | | */ |
99 | | static unsigned |
100 | | fStartConfirmed(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, uint8_t ack, |
101 | | int *svc, proto_item **tt); |
102 | | |
103 | | /** |
104 | | * Unconfirmed-Request-PDU ::= SEQUENCE { |
105 | | * pdu-type [0] Unsigned (0..15), -- 1 for this PDU type |
106 | | * reserved [1] Unsigned (0..15), -- must be set zero |
107 | | * service-choice [2] BACnetUnconfirmedServiceChoice, |
108 | | * service-request [3] BACnetUnconfirmedServiceRequest -- Context-specific tags 0..3 are NOT used in header encoding |
109 | | * } |
110 | | * @param tvb the tv buffer of the current data |
111 | | * @param pinfo the packet info of the current data |
112 | | * @param tree the tree to append this item to |
113 | | * @param offset the offset in the tvb |
114 | | * @return modified offset |
115 | | */ |
116 | | static unsigned |
117 | | fUnconfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
118 | | |
119 | | /** |
120 | | * SimpleACK-PDU ::= SEQUENCE { |
121 | | * pdu-type [0] Unsigned (0..15), -- 2 for this PDU type |
122 | | * reserved [1] Unsigned (0..15), -- must be set zero |
123 | | * invokeID [2] Unsigned (0..255), |
124 | | * service-ACK-choice [3] BACnetUnconfirmedServiceChoice -- Context-specific tags 0..3 are NOT used in header encoding |
125 | | * } |
126 | | * @param tvb the tv buffer of the current data |
127 | | * @param pinfo the packet info of the current data |
128 | | * @param tree the tree to append this item to |
129 | | * @param offset the offset in the tvb |
130 | | * @return modified offset |
131 | | */ |
132 | | static unsigned |
133 | | fSimpleAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
134 | | |
135 | | /** |
136 | | * ComplexACK-PDU ::= SEQUENCE { |
137 | | * pdu-type [0] Unsigned (0..15), -- 3 for this PDU Type |
138 | | * segmentedMessage [1] BOOLEAN, |
139 | | * moreFollows [2] BOOLEAN, |
140 | | * reserved [3] Unsigned (0..3), -- must be set zero |
141 | | * invokeID [4] Unsigned (0..255), |
142 | | * sequence-number [5] Unsigned (0..255) OPTIONAL, -- only if segmented msg |
143 | | * proposed-window-size [6] Unsigned (0..127) OPTIONAL, -- only if segmented msg |
144 | | * service-ACK-choice [7] BACnetConfirmedServiceChoice, |
145 | | * service-ACK [8] BACnet-Confirmed-Service-Request -- Context-specific tags 0..8 are NOT used in header encoding |
146 | | * } |
147 | | * @param tvb the tv buffer of the current data |
148 | | * @param pinfo the packet info of the current data |
149 | | * @param tree the tree to append this item to |
150 | | * @param offset the offset in the tvb |
151 | | * @return modified offset |
152 | | */ |
153 | | static unsigned |
154 | | fComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
155 | | |
156 | | /** |
157 | | * SegmentACK-PDU ::= SEQUENCE { |
158 | | * pdu-type [0] Unsigned (0..15), -- 4 for this PDU Type |
159 | | * reserved [1] Unsigned (0..3), -- must be set zero |
160 | | * negative-ACK [2] BOOLEAN, |
161 | | * server [3] BOOLEAN, |
162 | | * original-invokeID [4] Unsigned (0..255), |
163 | | * sequence-number [5] Unsigned (0..255), |
164 | | * actual-window-size [6] Unsigned (0..127) |
165 | | * } |
166 | | * @param tvb the tv buffer of the current data |
167 | | * @param pinfo the packet info of the current data |
168 | | * @param tree the tree to append this item to |
169 | | * @param offset the offset in the tvb |
170 | | * @return modified offset |
171 | | */ |
172 | | static unsigned |
173 | | fSegmentAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
174 | | |
175 | | /** |
176 | | * Error-PDU ::= SEQUENCE { |
177 | | * pdu-type [0] Unsigned (0..15), -- 5 for this PDU Type |
178 | | * reserved [1] Unsigned (0..3), -- must be set zero |
179 | | * original-invokeID [2] Unsigned (0..255), |
180 | | * error-choice [3] BACnetConfirmedServiceChoice, |
181 | | * error [4] BACnet-Error |
182 | | * } |
183 | | * @param tvb the tv buffer of the current data |
184 | | * @param pinfo the packet info of the current data |
185 | | * @param tree the tree to append this item to |
186 | | * @param offset the offset in the tvb |
187 | | * @return modified offset |
188 | | */ |
189 | | static unsigned |
190 | | fErrorPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
191 | | |
192 | | /** |
193 | | * Reject-PDU ::= SEQUENCE { |
194 | | * pdu-type [0] Unsigned (0..15), -- 6 for this PDU Type |
195 | | * reserved [1] Unsigned (0..3), -- must be set zero |
196 | | * original-invokeID [2] Unsigned (0..255), |
197 | | * reject-reason [3] BACnetRejectReason |
198 | | * } |
199 | | * @param tvb the tv buffer of the current data |
200 | | * @param pinfo the packet info of the current data |
201 | | * @param tree the tree to append this item to |
202 | | * @param offset the offset in the tvb |
203 | | * @return modified offset |
204 | | */ |
205 | | static unsigned |
206 | | fRejectPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
207 | | |
208 | | /** |
209 | | * Abort-PDU ::= SEQUENCE { |
210 | | * pdu-type [0] Unsigned (0..15), -- 7 for this PDU Type |
211 | | * reserved [1] Unsigned (0..3), -- must be set zero |
212 | | * server [2] BOOLEAN, |
213 | | * original-invokeID [3] Unsigned (0..255), |
214 | | * abort-reason [4] BACnetAbortReason |
215 | | * } |
216 | | * @param tvb the tv buffer of the current data |
217 | | * @param pinfo the packet info of the current data |
218 | | * @param tree the tree to append this item to |
219 | | * @param offset the offset in the tvb |
220 | | * @return modified offset |
221 | | */ |
222 | | static unsigned |
223 | | fAbortPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
224 | | |
225 | | /** |
226 | | * 20.2.4, adds the label with max 64Bit unsigned Integer Value to tree |
227 | | * @param tvb the tv buffer of the current data |
228 | | * @param pinfo the packet info of the current data |
229 | | * @param tree the tree to append this item to |
230 | | * @param offset the offset in the tvb |
231 | | * @param label the label of this item |
232 | | * @return modified offset |
233 | | */ |
234 | | static unsigned |
235 | | fUnsignedTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label); |
236 | | |
237 | | /** |
238 | | * 20.2.5, adds the label with max 64Bit signed Integer Value to tree |
239 | | * @param tvb the tv buffer of the current data |
240 | | * @param pinfo the packet info of the current data |
241 | | * @param tree the tree to append this item to |
242 | | * @param offset the offset in the tvb |
243 | | * @param label the label of this item |
244 | | * @return modified offset |
245 | | */ |
246 | | static unsigned |
247 | | fSignedTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label); |
248 | | |
249 | | /** |
250 | | * 20.2.8, adds the label with Octet String to tree; if lvt == 0 then lvt = restOfFrame |
251 | | * @param tvb the tv buffer of the current data |
252 | | * @param pinfo the packet info of the current data |
253 | | * @param tree the tree to append this item to |
254 | | * @param offset the offset in the tvb |
255 | | * @param label the label of this item |
256 | | * @param lvt length of String |
257 | | * @return modified offset |
258 | | */ |
259 | | static unsigned |
260 | | fOctetString(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label, uint32_t lvt); |
261 | | |
262 | | /** |
263 | | * 20.2.12, adds the label with Date Value to tree |
264 | | * @param tvb the tv buffer of the current data |
265 | | * @param pinfo the packet info of the current data |
266 | | * @param tree the tree to append this item to |
267 | | * @param offset the offset in the tvb |
268 | | * @param label the label of this item |
269 | | * @return modified offset |
270 | | */ |
271 | | static unsigned |
272 | | fDate(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label); |
273 | | |
274 | | /** |
275 | | * 20.2.13, adds the label with Time Value to tree |
276 | | * @param tvb the tv buffer of the current data |
277 | | * @param pinfo the packet info of the current data |
278 | | * @param tree the tree to append this item to |
279 | | * @param offset the offset in the tvb |
280 | | * @param label the label of this item |
281 | | * @return modified offset |
282 | | */ |
283 | | static unsigned |
284 | | fTime(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label); |
285 | | |
286 | | /** |
287 | | * 20.2.14, adds Object Identifier to tree |
288 | | * use BIG ENDIAN: Bits 31..22 Object Type, Bits 21..0 Instance Number |
289 | | * @param tvb the tv buffer of the current data |
290 | | * @param pinfo the packet info of the current data |
291 | | * @param tree the tree to append this item to |
292 | | * @param offset the offset in the tvb |
293 | | * @param hfid the hfid of the item to use (e.g., hf_bacapp_object_identifier |
294 | | * or hf_bacapp_device_identifier) |
295 | | * @return modified offset |
296 | | */ |
297 | | static unsigned |
298 | | fObjectIdentifier(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, int hfid); |
299 | | |
300 | | /** |
301 | | * BACnet-Confirmed-Service-Request ::= CHOICE { |
302 | | * } |
303 | | * @param tvb the tv buffer of the current data |
304 | | * @param pinfo the packet info of the current data |
305 | | * @param tree the tree to append this item to |
306 | | * @param offset the offset in the tvb |
307 | | * @param service_choice the service choice |
308 | | * @return offset |
309 | | */ |
310 | | static unsigned |
311 | | fConfirmedServiceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, int service_choice); |
312 | | |
313 | | /** |
314 | | * BACnet-Confirmed-Service-ACK ::= CHOICE { |
315 | | * } |
316 | | * @param tvb the tv buffer of the current data |
317 | | * @param pinfo the packet info of the current data |
318 | | * @param tree the tree to append this item to |
319 | | * @param offset the offset in the tvb |
320 | | * @param service_choice the service choice |
321 | | * @return offset |
322 | | */ |
323 | | static unsigned |
324 | | fConfirmedServiceAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, int service_choice); |
325 | | |
326 | | /** |
327 | | * AcknowledgeAlarm-Request ::= SEQUENCE { |
328 | | * acknowledgingProcessIdentifier [0] Unsigned32, |
329 | | * eventObjectIdentifier [1] BACnetObjectIdentifier, |
330 | | * eventStateAcknowledge [2] BACnetEventState, |
331 | | * timeStamp [3] BACnetTimeStamp, |
332 | | * acknowledgementSource [4] Character String, |
333 | | * timeOfAcknowledgement [5] BACnetTimeStamp |
334 | | * } |
335 | | * @param tvb the tv buffer of the current data |
336 | | * @param pinfo the packet info of the current data |
337 | | * @param tree the tree to append this item to |
338 | | * @param offset the offset in the tvb |
339 | | * @return modified offset |
340 | | */ |
341 | | static unsigned |
342 | | fAcknowledgeAlarmRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
343 | | |
344 | | /** |
345 | | * ConfirmedCOVNotification-Request ::= SEQUENCE { |
346 | | * subscriberProcessIdentifier [0] Unsigned32, |
347 | | * initiatingDeviceIdentifier [1] BACnetObjectIdentifier, |
348 | | * monitoredObjectIdentifier [2] BACnetObjectIdentifier, |
349 | | * timeRemaining [3] unsigned, |
350 | | * listOfValues [4] SEQUENCE OF BACnetPropertyValues |
351 | | * } |
352 | | * @param tvb the tv buffer of the current data |
353 | | * @param pinfo the packet info of the current data |
354 | | * @param tree the tree to append this item to |
355 | | * @param offset the offset in the tvb |
356 | | * @return modified offset |
357 | | */ |
358 | | static unsigned |
359 | | fConfirmedCOVNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
360 | | |
361 | | /** |
362 | | * ConfirmedEventNotification-Request ::= SEQUENCE { |
363 | | * ProcessIdentifier [0] Unsigned32, |
364 | | * initiatingDeviceIdentifier [1] BACnetObjectIdentifier, |
365 | | * eventObjectIdentifier [2] BACnetObjectIdentifier, |
366 | | * timeStamp [3] BACnetTimeStamp, |
367 | | * notificationClass [4] unsigned, |
368 | | * priority [5] unsigned8, |
369 | | * eventType [6] BACnetEventType, |
370 | | * messageText [7] CharacterString OPTIONAL, |
371 | | * notifyType [8] BACnetNotifyType, |
372 | | * ackRequired [9] BOOLEAN OPTIONAL, |
373 | | * fromState [10] BACnetEventState OPTIONAL, |
374 | | * toState [11] BACnetEventState, |
375 | | * eventValues [12] BACnetNotificationParameters OPTIONAL |
376 | | * } |
377 | | * @param tvb the tv buffer of the current data |
378 | | * @param pinfo the packet info of the current data |
379 | | * @param tree the tree to append this item to |
380 | | * @param offset the offset in the tvb |
381 | | * @return modified offset |
382 | | */ |
383 | | static unsigned |
384 | | fConfirmedEventNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
385 | | |
386 | | /** |
387 | | * GetAlarmSummary-ACK ::= SEQUENCE OF SEQUENCE { |
388 | | * objectIdentifier BACnetObjectIdentifier, |
389 | | * alarmState BACnetEventState, |
390 | | * acknowledgedTransitions BACnetEventTransitionBits |
391 | | * } |
392 | | * @param tvb the tv buffer of the current data |
393 | | * @param pinfo the packet info of the current data |
394 | | * @param tree the tree to append this item to |
395 | | * @param offset the offset in the tvb |
396 | | * @return modified offset |
397 | | */ |
398 | | static unsigned |
399 | | fGetAlarmSummaryAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
400 | | |
401 | | /** |
402 | | * GetEnrollmentSummary-Request ::= SEQUENCE { |
403 | | * acknowledgmentFilter [0] ENUMERATED { |
404 | | * all (0), |
405 | | * acked (1), |
406 | | * not-acked (2) |
407 | | * }, |
408 | | * enrollmentFilter [1] BACnetRecipientProcess OPTIONAL, |
409 | | * eventStateFilter [2] ENUMERATED { |
410 | | * offnormal (0), |
411 | | * fault (1), |
412 | | * normal (2), |
413 | | * all (3), |
414 | | * active (4) |
415 | | * }, |
416 | | * eventTypeFilter [3] BACnetEventType OPTIONAL, |
417 | | * priorityFilter [4] SEQUENCE { |
418 | | * minPriority [0] Unsigned8, |
419 | | * maxPriority [1] Unsigned8 |
420 | | * } OPTIONAL, |
421 | | * notificationClassFilter [5] Unsigned OPTIONAL |
422 | | * } |
423 | | * @param tvb the tv buffer of the current data |
424 | | * @param pinfo the packet info of the current data |
425 | | * @param tree the tree to append this item to |
426 | | * @param offset the offset in the tvb |
427 | | * @return modified offset |
428 | | */ |
429 | | static unsigned |
430 | | fGetEnrollmentSummaryRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
431 | | |
432 | | /** |
433 | | * GetEnrollmentSummary-ACK ::= SEQUENCE OF SEQUENCE { |
434 | | * objectIdentifier BACnetObjectIdentifier, |
435 | | * eventType BACnetEventType, |
436 | | * eventState BACnetEventState, |
437 | | * priority Unsigned8, |
438 | | * notificationClass Unsigned OPTIONAL |
439 | | * } |
440 | | * @param tvb the tv buffer of the current data |
441 | | * @param pinfo the packet info of the current data |
442 | | * @param tree the tree to append this item to |
443 | | * @param offset the offset in the tvb |
444 | | * @return modified offset |
445 | | */ |
446 | | static unsigned |
447 | | fGetEnrollmentSummaryAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
448 | | |
449 | | /** |
450 | | * GetEventInformation-Request ::= SEQUENCE { |
451 | | * lastReceivedObjectIdentifier [0] BACnetObjectIdentifier |
452 | | * } |
453 | | * @param tvb the tv buffer of the current data |
454 | | * @param pinfo the packet info of the current data |
455 | | * @param tree the tree to append this item to |
456 | | * @param offset the offset in the tvb |
457 | | * @return modified offset |
458 | | */ |
459 | | static unsigned |
460 | | fGetEventInformationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
461 | | |
462 | | /** |
463 | | * GetEventInformation-ACK ::= SEQUENCE { |
464 | | * listOfEventSummaries [0] listOfEventSummaries, |
465 | | * moreEvents [1] BOOLEAN |
466 | | * } |
467 | | * @param tvb the tv buffer of the current data |
468 | | * @param pinfo the packet info of the current data |
469 | | * @param tree the tree to append this item to |
470 | | * @param offset the offset in the tvb |
471 | | * @return modified offset |
472 | | */ |
473 | | static unsigned |
474 | | fGetEventInformationACK(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
475 | | |
476 | | /** |
477 | | * LifeSafetyOperation-Request ::= SEQUENCE { |
478 | | * requestingProcessIdentifier [0] Unsigned32 |
479 | | * requestingSource [1] CharacterString |
480 | | * request [2] BACnetLifeSafetyOperation |
481 | | * objectIdentifier [3] BACnetObjectIdentifier OPTIONAL |
482 | | * } |
483 | | * @param tvb the tv buffer of the current data |
484 | | * @param pinfo the packet info of the current data |
485 | | * @param tree the tree to append this item to |
486 | | * @param offset the offset in the tvb |
487 | | * @return modified offset |
488 | | */ |
489 | | static unsigned |
490 | | fLifeSafetyOperationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label); |
491 | | |
492 | | /** |
493 | | * SubscribeCOV-Request ::= SEQUENCE { |
494 | | * subscriberProcessIdentifier [0] Unsigned32 |
495 | | * monitoredObjectIdentifier [1] BACnetObjectIdentifier |
496 | | * issueConfirmedNotifications [2] BOOLEAN OPTIONAL |
497 | | * lifetime [3] Unsigned OPTIONAL |
498 | | * } |
499 | | * @param tvb the tv buffer of the current data |
500 | | * @param pinfo the packet info of the current data |
501 | | * @param tree the tree to append this item to |
502 | | * @param offset the offset in the tvb |
503 | | * @return modified offset |
504 | | */ |
505 | | static unsigned |
506 | | fSubscribeCOVRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
507 | | |
508 | | /** |
509 | | * SubscribeCOVProperty-Request ::= SEQUENCE { |
510 | | * subscriberProcessIdentifier [0] Unsigned32 |
511 | | * monitoredObjectIdentifier [1] BACnetObjectIdentifier |
512 | | * issueConfirmedNotifications [2] BOOLEAN OPTIONAL |
513 | | * lifetime [3] Unsigned OPTIONAL |
514 | | * monitoredPropertyIdentifier [4] BACnetPropertyReference OPTIONAL |
515 | | * covIncrement [5] Unsigned OPTIONAL |
516 | | * } |
517 | | * @param tvb the tv buffer of the current data |
518 | | * @param pinfo the packet info of the current data |
519 | | * @param tree the tree to append this item to |
520 | | * @param offset the offset in the tvb |
521 | | * @return modified offset |
522 | | */ |
523 | | static unsigned |
524 | | fSubscribeCOVPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
525 | | |
526 | | /** |
527 | | * AtomicReadFile-Request ::= SEQUENCE { |
528 | | * fileIdentifier BACnetObjectIdentifier, |
529 | | * accessMethod CHOICE { |
530 | | * streamAccess [0] SEQUENCE { |
531 | | * fileStartPosition INTEGER, |
532 | | * requestedOctetCount Unsigned |
533 | | * }, |
534 | | * recordAccess [1] SEQUENCE { |
535 | | * fileStartRecord INTEGER, |
536 | | * requestedRecordCount Unsigned |
537 | | * } |
538 | | * } |
539 | | * } |
540 | | * @param tvb the tv buffer of the current data |
541 | | * @param pinfo the packet info of the current data |
542 | | * @param tree the tree to append this item to |
543 | | * @param offset the offset in the tvb |
544 | | * @return modified offset |
545 | | */ |
546 | | static unsigned |
547 | | fAtomicReadFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
548 | | |
549 | | /** |
550 | | * AtomicWriteFile-ACK ::= SEQUENCE { |
551 | | * endOfFile BOOLEAN, |
552 | | * accessMethod CHOICE { |
553 | | * streamAccess [0] SEQUENCE { |
554 | | * fileStartPosition INTEGER, |
555 | | * fileData OCTET STRING |
556 | | * }, |
557 | | * recordAccess [1] SEQUENCE { |
558 | | * fileStartRecord INTEGER, |
559 | | * returnedRecordCount Unsigned, |
560 | | * fileRecordData SEQUENCE OF OCTET STRING |
561 | | * } |
562 | | * } |
563 | | * } |
564 | | * @param tvb the tv buffer of the current data |
565 | | * @param pinfo the packet info of the current data |
566 | | * @param tree the tree to append this item to |
567 | | * @param offset the offset in the tvb |
568 | | * @return modified offset |
569 | | */ |
570 | | static unsigned |
571 | | fAtomicReadFileAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
572 | | |
573 | | /** |
574 | | * AtomicWriteFile-Request ::= SEQUENCE { |
575 | | * fileIdentifier BACnetObjectIdentifier, |
576 | | * accessMethod CHOICE { |
577 | | * streamAccess [0] SEQUENCE { |
578 | | * fileStartPosition INTEGER, |
579 | | * fileData OCTET STRING |
580 | | * }, |
581 | | * recordAccess [1] SEQUENCE { |
582 | | * fileStartRecord INTEGER, |
583 | | * recordCount Unsigned, |
584 | | * fileRecordData SEQUENCE OF OCTET STRING |
585 | | * } |
586 | | * } |
587 | | * } |
588 | | * @param tvb the tv buffer of the current data |
589 | | * @param pinfo the packet info of the current data |
590 | | * @param tree the tree to append this item to |
591 | | * @param offset the offset in the tvb |
592 | | * @return modified offset |
593 | | */ |
594 | | static unsigned |
595 | | fAtomicWriteFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
596 | | |
597 | | /** |
598 | | * AtomicWriteFile-ACK ::= SEQUENCE { |
599 | | * fileStartPosition [0] INTEGER, |
600 | | * fileStartRecord [1] INTEGER, |
601 | | * } |
602 | | * @param tvb the tv buffer of the current data |
603 | | * @param pinfo the packet info of the current data |
604 | | * @param tree the tree to append this item to |
605 | | * @param offset the offset in the tvb |
606 | | * @return modified offset |
607 | | */ |
608 | | static unsigned |
609 | | fAtomicWriteFileAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
610 | | |
611 | | /** |
612 | | * AddListElement-Request ::= SEQUENCE { |
613 | | * objectIdentifier [0] BACnetObjectIdentifier, |
614 | | * propertyIdentifier [1] BACnetPropertyIdentifier, |
615 | | * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype |
616 | | * listOfElements [3] ABSTRACT-SYNTAX.&Type |
617 | | * } |
618 | | * @param tvb the tv buffer of the current data |
619 | | * @param pinfo the packet info of the current data |
620 | | * @param tree the tree to append this item to |
621 | | * @param offset the offset in the tvb |
622 | | * @return modified offset |
623 | | */ |
624 | | static unsigned |
625 | | fAddListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
626 | | |
627 | | /** |
628 | | * CreateObject-Request ::= SEQUENCE { |
629 | | * objectSpecifier [0] ObjectSpecifier, |
630 | | * listOfInitialValues [1] SEQUENCE OF BACnetPropertyValue OPTIONAL |
631 | | * } |
632 | | * @param tvb the tv buffer of the current data |
633 | | * @param pinfo the packet info of the current data |
634 | | * @param subtree the sub tree to append this item to |
635 | | * @param offset the offset in the tvb |
636 | | * @return modified offset |
637 | | */ |
638 | | static unsigned |
639 | | fCreateObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, unsigned offset); |
640 | | |
641 | | /** |
642 | | * CreateObject-Request ::= BACnetObjectIdentifier |
643 | | * @param tvb the tv buffer of the current data |
644 | | * @param pinfo the packet info of the current data |
645 | | * @param tree the tree to append this item to |
646 | | * @param offset the offset in the tvb |
647 | | * @return modified offset |
648 | | */ |
649 | | static unsigned |
650 | | fCreateObjectAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
651 | | |
652 | | /** |
653 | | * DeleteObject-Request ::= SEQUENCE { |
654 | | * ObjectIdentifier BACnetObjectIdentifier |
655 | | * } |
656 | | * @param tvb the tv buffer of the current data |
657 | | * @param pinfo the packet info of the current data |
658 | | * @param tree the tree to append this item to |
659 | | * @param offset the offset in the tvb |
660 | | * @return modified offset |
661 | | */ |
662 | | static unsigned |
663 | | fDeleteObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
664 | | |
665 | | /** |
666 | | * ReadProperty-Request ::= SEQUENCE { |
667 | | * objectIdentifier [0] BACnetObjectIdentifier, |
668 | | * propertyIdentifier [1] BACnetPropertyIdentifier, |
669 | | * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype |
670 | | * } |
671 | | * @param tvb the tv buffer of the current data |
672 | | * @param pinfo the packet info of the current data |
673 | | * @param tree the tree to append this item to |
674 | | * @param offset the offset in the tvb |
675 | | * @return modified offset |
676 | | */ |
677 | | static unsigned |
678 | | fReadPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
679 | | |
680 | | /** |
681 | | * ReadProperty-ACK ::= SEQUENCE { |
682 | | * objectIdentifier [0] BACnetObjectIdentifier, |
683 | | * propertyIdentifier [1] BACnetPropertyIdentifier, |
684 | | * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype |
685 | | * propertyValue [3] ABSTRACT-SYNTAX.&Type |
686 | | * } |
687 | | * @param tvb the tv buffer of the current data |
688 | | * @param pinfo the packet info of the current data |
689 | | * @param tree the tree to append this item to |
690 | | * @param offset the offset in the tvb |
691 | | * @return modified offset |
692 | | */ |
693 | | static unsigned |
694 | | fReadPropertyAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
695 | | |
696 | | /** |
697 | | * ReadPropertyConditional-Request ::= SEQUENCE { |
698 | | * objectSelectionCriteria [0] objectSelectionCriteria, |
699 | | * listOfPropertyReferences [1] SEQUENCE OF BACnetPropertyReference OPTIONAL |
700 | | * } |
701 | | * @param tvb the tv buffer of the current data |
702 | | * @param pinfo the packet info of the current data |
703 | | * @param subtree the sub tree to append this item to |
704 | | * @param offset the offset in the tvb |
705 | | * @return modified offset |
706 | | */ |
707 | | static unsigned |
708 | | fReadPropertyConditionalRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, unsigned offset); |
709 | | |
710 | | /** |
711 | | * ReadPropertyConditional-ACK ::= SEQUENCE { |
712 | | * listOfPReadAccessResults SEQUENCE OF ReadAccessResult OPTIONAL |
713 | | * } |
714 | | * @param tvb the tv buffer of the current data |
715 | | * @param pinfo the packet info of the current data |
716 | | * @param tree the tree to append this item to |
717 | | * @param offset the offset in the tvb |
718 | | * @return modified offset |
719 | | */ |
720 | | static unsigned |
721 | | fReadPropertyConditionalAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
722 | | |
723 | | /** |
724 | | * ReadPropertyMultiple-Request ::= SEQUENCE { |
725 | | * listOfReadAccessSpecs SEQUENCE OF ReadAccessSpecification |
726 | | * } |
727 | | * @param tvb the tv buffer of the current data |
728 | | * @param pinfo the packet info of the current data |
729 | | * @param subtree the sub tree to append this item to |
730 | | * @param offset the offset in the tvb |
731 | | * @return offset modified |
732 | | */ |
733 | | static unsigned |
734 | | fReadPropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, unsigned offset); |
735 | | |
736 | | /** |
737 | | * ReadPropertyMultiple-Ack ::= SEQUENCE { |
738 | | * listOfReadAccessResults SEQUENCE OF ReadAccessResult |
739 | | * } |
740 | | * @param tvb the tv buffer of the current data |
741 | | * @param pinfo the packet info of the current data |
742 | | * @param tree the tree to append this item to |
743 | | * @param offset the offset in the tvb |
744 | | * @return offset modified |
745 | | */ |
746 | | static unsigned |
747 | | fReadPropertyMultipleAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
748 | | |
749 | | /** |
750 | | * ReadRange-Request ::= SEQUENCE { |
751 | | * objectIdentifier [0] BACnetObjectIdentifier, |
752 | | * propertyIdentifier [1] BACnetPropertyIdentifier, |
753 | | * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype |
754 | | * range CHOICE { |
755 | | * byPosition [3] SEQUENCE { |
756 | | * referencedIndex Unsigned, |
757 | | * count INTEGER |
758 | | * }, |
759 | | * byTime [4] SEQUENCE { |
760 | | * referenceTime BACnetDateTime, |
761 | | * count INTEGER |
762 | | * }, |
763 | | * timeRange [5] SEQUENCE { |
764 | | * beginningTime BACnetDateTime, |
765 | | * endingTime BACnetDateTime |
766 | | * }, |
767 | | * } OPTIONAL |
768 | | * } |
769 | | * @param tvb the tv buffer of the current data |
770 | | * @param pinfo the packet info of the current data |
771 | | * @param tree the tree to append this item to |
772 | | * @param offset the offset in the tvb |
773 | | * @return modified offset |
774 | | */ |
775 | | static unsigned |
776 | | fReadRangeRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
777 | | |
778 | | /** |
779 | | * ReadRange-ACK ::= SEQUENCE { |
780 | | * objectIdentifier [0] BACnetObjectIdentifier, |
781 | | * propertyIdentifier [1] BACnetPropertyIdentifier, |
782 | | * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype |
783 | | * resultFlags [3] BACnetResultFlags, |
784 | | * itemCount [4] Unsigned, |
785 | | * itemData [5] SEQUENCE OF ABSTRACT-SYNTAX.&Type |
786 | | * } |
787 | | * @param tvb the tv buffer of the current data |
788 | | * @param pinfo the packet info of the current data |
789 | | * @param tree the tree to append this item to |
790 | | * @param offset the offset in the tvb |
791 | | * @return modified offset |
792 | | */ |
793 | | static unsigned |
794 | | fReadRangeAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
795 | | |
796 | | /** |
797 | | * RemoveListElement-Request ::= SEQUENCE { |
798 | | * objectIdentifier [0] BACnetObjectIdentifier, |
799 | | * propertyIdentifier [1] BACnetPropertyIdentifier, |
800 | | * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype |
801 | | * listOfElements [3] ABSTRACT-SYNTAX.&Type |
802 | | * } |
803 | | * @param tvb the tv buffer of the current data |
804 | | * @param pinfo the packet info of the current data |
805 | | * @param tree the tree to append this item to |
806 | | * @param offset the offset in the tvb |
807 | | * @return modified offset |
808 | | */ |
809 | | static unsigned |
810 | | fRemoveListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
811 | | |
812 | | /** |
813 | | * WriteProperty-Request ::= SEQUENCE { |
814 | | * objectIdentifier [0] BACnetObjectIdentifier, |
815 | | * propertyIdentifier [1] BACnetPropertyIdentifier, |
816 | | * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype |
817 | | * propertyValue [3] ABSTRACT-SYNTAX.&Type |
818 | | * priority [4] Unsigned8 (1..16) OPTIONAL --used only when property is commandable |
819 | | * } |
820 | | * @param tvb the tv buffer of the current data |
821 | | * @param pinfo the packet info of the current data |
822 | | * @param tree the tree to append this item to |
823 | | * @param offset the offset in the tvb |
824 | | * @return modified offset |
825 | | */ |
826 | | static unsigned |
827 | | fWritePropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
828 | | |
829 | | /** |
830 | | * WritePropertyMultiple-Request ::= SEQUENCE { |
831 | | * listOfWriteAccessSpecifications SEQUENCE OF WriteAccessSpecification |
832 | | * } |
833 | | * @param tvb the tv buffer of the current data |
834 | | * @param pinfo the packet info of the current data |
835 | | * @param tree the tree to append this item to |
836 | | * @param offset the offset in the tvb |
837 | | * @return modified offset |
838 | | */ |
839 | | static unsigned |
840 | | fWritePropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
841 | | |
842 | | /** |
843 | | * DeviceCommunicationControl-Request ::= SEQUENCE { |
844 | | * timeDuration [0] Unsigned16 OPTIONAL, |
845 | | * enable-disable [1] ENUMERATED { |
846 | | * enable (0), |
847 | | * disable (1) |
848 | | * }, |
849 | | * password [2] CharacterString (SIZE(1..20)) OPTIONAL |
850 | | * } |
851 | | * @param tvb the tv buffer of the current data |
852 | | * @param pinfo the packet info of the current data |
853 | | * @param tree the tree to append this item to |
854 | | * @param offset the offset in the tvb |
855 | | * @return modified offset |
856 | | */ |
857 | | static unsigned |
858 | | fDeviceCommunicationControlRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
859 | | |
860 | | /** |
861 | | * ConfirmedPrivateTransfer-Request ::= SEQUENCE { |
862 | | * vendorID [0] Unsigned, |
863 | | * serviceNumber [1] Unsigned, |
864 | | * serviceParameters [2] ABSTRACT-SYNTAX.&Type OPTIONAL |
865 | | * } |
866 | | * @param tvb the tv buffer of the current data |
867 | | * @param pinfo the packet info of the current data |
868 | | * @param tree the tree to append this item to |
869 | | * @param offset the offset in the tvb |
870 | | * @return modified offset |
871 | | */ |
872 | | static unsigned |
873 | | fConfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
874 | | |
875 | | /** |
876 | | * ConfirmedPrivateTransfer-ACK ::= SEQUENCE { |
877 | | * vendorID [0] Unsigned, |
878 | | * serviceNumber [1] Unsigned, |
879 | | * resultBlock [2] ABSTRACT-SYNTAX.&Type OPTIONAL |
880 | | * } |
881 | | * @param tvb the tv buffer of the current data |
882 | | * @param pinfo the packet info of the current data |
883 | | * @param tree the tree to append this item to |
884 | | * @param offset the offset in the tvb |
885 | | * @return modified offset |
886 | | */ |
887 | | static unsigned |
888 | | fConfirmedPrivateTransferAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
889 | | |
890 | | /** |
891 | | * ConfirmedTextMessage-Request ::= SEQUENCE { |
892 | | * textMessageSourceDevice [0] BACnetObjectIdentifier, |
893 | | * messageClass [1] CHOICE { |
894 | | * numeric [0] Unsigned, |
895 | | * character [1] CharacterString |
896 | | * } OPTIONAL, |
897 | | * messagePriority [2] ENUMERATED { |
898 | | * normal (0), |
899 | | * urgent (1) |
900 | | * }, |
901 | | * message [3] CharacterString |
902 | | * } |
903 | | * @param tvb the tv buffer of the current data |
904 | | * @param pinfo the packet info of the current data |
905 | | * @param tree the tree to append this item to |
906 | | * @param offset the offset in the tvb |
907 | | * @return modified offset |
908 | | */ |
909 | | static unsigned |
910 | | fConfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
911 | | |
912 | | /** |
913 | | * ReinitializeDevice-Request ::= SEQUENCE { |
914 | | * reinitializedStateOfDevice [0] ENUMERATED { |
915 | | * coldstart (0), |
916 | | * warmstart (1), |
917 | | * startbackup (2), |
918 | | * endbackup (3), |
919 | | * startrestore (4), |
920 | | * endrestore (5), |
921 | | * abortrestor (6) |
922 | | * }, |
923 | | * password [1] CharacterString (SIZE(1..20)) OPTIONAL |
924 | | * } |
925 | | * @param tvb the tv buffer of the current data |
926 | | * @param pinfo the packet info of the current data |
927 | | * @param tree the tree to append this item to |
928 | | * @param offset the offset in the tvb |
929 | | * @return modified offset |
930 | | */ |
931 | | static unsigned |
932 | | fReinitializeDeviceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
933 | | |
934 | | /** |
935 | | * VTOpen-Request ::= SEQUENCE { |
936 | | * vtClass BACnetVTClass, |
937 | | * localVTSessionIdentifier Unsigned8 |
938 | | * } |
939 | | * @param tvb the tv buffer of the current data |
940 | | * @param pinfo the packet info of the current data |
941 | | * @param tree the tree to append this item to |
942 | | * @param offset the offset in the tvb |
943 | | * @return modified offset |
944 | | */ |
945 | | static unsigned |
946 | | fVtOpenRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
947 | | |
948 | | /** |
949 | | * VTOpen-ACK ::= SEQUENCE { |
950 | | * remoteVTSessionIdentifier Unsigned8 |
951 | | * } |
952 | | * @param tvb the tv buffer of the current data |
953 | | * @param pinfo the packet info of the current data |
954 | | * @param tree the tree to append this item to |
955 | | * @param offset the offset in the tvb |
956 | | * @return modified offset |
957 | | */ |
958 | | static unsigned |
959 | | fVtOpenAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
960 | | |
961 | | /** |
962 | | * VTClose-Request ::= SEQUENCE { |
963 | | * listOfRemoteVTSessionIdentifiers SEQUENCE OF Unsigned8 |
964 | | * } |
965 | | * @param tvb the tv buffer of the current data |
966 | | * @param pinfo the packet info of the current data |
967 | | * @param tree the tree to append this item to |
968 | | * @param offset the offset in the tvb |
969 | | * @return modified offset |
970 | | */ |
971 | | static unsigned |
972 | | fVtCloseRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
973 | | |
974 | | /** |
975 | | * VTData-Request ::= SEQUENCE { |
976 | | * vtSessionIdentifier Unsigned8, |
977 | | * vtNewData OCTET STRING, |
978 | | * vtDataFlag Unsigned (0..1) |
979 | | * } |
980 | | * @param tvb the tv buffer of the current data |
981 | | * @param pinfo the packet info of the current data |
982 | | * @param tree the tree to append this item to |
983 | | * @param offset the offset in the tvb |
984 | | * @return modified offset |
985 | | */ |
986 | | static unsigned |
987 | | fVtDataRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
988 | | |
989 | | /** |
990 | | * VTData-ACK ::= SEQUENCE { |
991 | | * allNewDataAccepted [0] BOOLEAN, |
992 | | * acceptedOctetCount [1] Unsigned OPTIONAL -- present only if allNewDataAccepted = false |
993 | | * } |
994 | | * @param tvb the tv buffer of the current data |
995 | | * @param pinfo the packet info of the current data |
996 | | * @param tree the tree to append this item to |
997 | | * @param offset the offset in the tvb |
998 | | * @return modified offset |
999 | | */ |
1000 | | static unsigned |
1001 | | fVtDataAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1002 | | |
1003 | | /** |
1004 | | * Authenticate-Request ::= SEQUENCE { |
1005 | | * pseudoRandomNumber [0] Unsigned32, |
1006 | | * expectedInvokeID [1] Unsigned8 OPTIONAL, |
1007 | | * operatorName [2] CharacterString OPTIONAL, |
1008 | | * operatorPassword [3] CharacterString (SIZE(1..20)) OPTIONAL, |
1009 | | * startEncypheredSession [4] BOOLEAN OPTIONAL |
1010 | | * } |
1011 | | * @param tvb the tv buffer of the current data |
1012 | | * @param pinfo the packet info of the current data |
1013 | | * @param tree the tree to append this item to |
1014 | | * @param offset the offset in the tvb |
1015 | | * @return modified offset |
1016 | | */ |
1017 | | static unsigned |
1018 | | fAuthenticateRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1019 | | |
1020 | | /** |
1021 | | * Authenticate-ACK ::= SEQUENCE { |
1022 | | * modifiedRandomNumber Unsigned32, |
1023 | | * } |
1024 | | * @param tvb the tv buffer of the current data |
1025 | | * @param pinfo the packet info of the current data |
1026 | | * @param tree the tree to append this item to |
1027 | | * @param offset the offset in the tvb |
1028 | | * @return modified offset |
1029 | | */ |
1030 | | static unsigned |
1031 | | fAuthenticateAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1032 | | |
1033 | | /** |
1034 | | * RequestKey-Request ::= SEQUENCE { |
1035 | | * requestingDeviceIdentifier BACnetObjectIdentifier, |
1036 | | * requestingDeviceAddress BACnetAddress, |
1037 | | * remoteDeviceIdentifier BACnetObjectIdentifier, |
1038 | | * remoteDeviceAddress BACnetAddress |
1039 | | * } |
1040 | | * @param tvb the tv buffer of the current data |
1041 | | * @param pinfo the packet info of the current data |
1042 | | * @param tree the tree to append this item to |
1043 | | * @param offset the offset in the tvb |
1044 | | * @return modified offset |
1045 | | */ |
1046 | | static unsigned |
1047 | | fRequestKeyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1048 | | |
1049 | | /** |
1050 | | * Unconfirmed-Service-Request ::= CHOICE { |
1051 | | * } |
1052 | | * @param tvb the tv buffer of the current data |
1053 | | * @param pinfo the packet info of the current data |
1054 | | * @param tree the tree to append this item to |
1055 | | * @param offset the offset in the tvb |
1056 | | * @param service_choice the service choice |
1057 | | * @return modified offset |
1058 | | */ |
1059 | | static unsigned |
1060 | | fUnconfirmedServiceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, int service_choice); |
1061 | | |
1062 | | /** |
1063 | | * UnconfirmedCOVNotification-Request ::= SEQUENCE { |
1064 | | * subscriberProcessIdentifier [0] Unsigned32, |
1065 | | * initiatingDeviceIdentifier [1] BACnetObjectIdentifier, |
1066 | | * monitoredObjectIdentifier [2] BACnetObjectIdentifier, |
1067 | | * timeRemaining [3] unsigned, |
1068 | | * listOfValues [4] SEQUENCE OF BACnetPropertyValues |
1069 | | * } |
1070 | | * @param tvb the tv buffer of the current data |
1071 | | * @param pinfo the packet info of the current data |
1072 | | * @param tree the tree to append this item to |
1073 | | * @param offset the offset in the tvb |
1074 | | * @return modified offset |
1075 | | */ |
1076 | | static unsigned |
1077 | | fUnconfirmedCOVNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1078 | | |
1079 | | /** |
1080 | | * UnconfirmedEventNotification-Request ::= SEQUENCE { |
1081 | | * ProcessIdentifier [0] Unsigned32, |
1082 | | * initiatingDeviceIdentifier [1] BACnetObjectIdentifier, |
1083 | | * eventObjectIdentifier [2] BACnetObjectIdentifier, |
1084 | | * timeStamp [3] BACnetTimeStamp, |
1085 | | * notificationClass [4] unsigned, |
1086 | | * priority [5] unsigned8, |
1087 | | * eventType [6] BACnetEventType, |
1088 | | * messageText [7] CharacterString OPTIONAL, |
1089 | | * notifyType [8] BACnetNotifyType, |
1090 | | * ackRequired [9] BOOLEAN OPTIONAL, |
1091 | | * fromState [10] BACnetEventState OPTIONAL, |
1092 | | * toState [11] BACnetEventState, |
1093 | | * eventValues [12] BACnetNotificationParameters OPTIONAL |
1094 | | * } |
1095 | | * @param tvb the tv buffer of the current data |
1096 | | * @param pinfo the packet info of the current data |
1097 | | * @param tree the tree to append this item to |
1098 | | * @param offset the offset in the tvb |
1099 | | * @return modified offset |
1100 | | */ |
1101 | | static unsigned |
1102 | | fUnconfirmedEventNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1103 | | |
1104 | | /** |
1105 | | * I-Am-Request ::= SEQUENCE { |
1106 | | * aAmDeviceIdentifier BACnetObjectIdentifier, |
1107 | | * maxAPDULengthAccepted Unsigned, |
1108 | | * segmentationSupported BACnetSegmentation, |
1109 | | * vendorID Unsigned |
1110 | | * } |
1111 | | * @param tvb the tv buffer of the current data |
1112 | | * @param pinfo the packet info of the current data |
1113 | | * @param tree the tree to append this item to |
1114 | | * @param offset the offset in the tvb |
1115 | | * @return modified offset |
1116 | | */ |
1117 | | static unsigned |
1118 | | fIAmRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1119 | | |
1120 | | |
1121 | | /** |
1122 | | * I-Have-Request ::= SEQUENCE { |
1123 | | * deviceIdentifier BACnetObjectIdentifier, |
1124 | | * objectIdentifier BACnetObjectIdentifier, |
1125 | | * objectName CharacterString |
1126 | | * } |
1127 | | * @param tvb the tv buffer of the current data |
1128 | | * @param pinfo the packet info of the current data |
1129 | | * @param tree the tree to append this item to |
1130 | | * @param offset the offset in the tvb |
1131 | | * @return modified offset |
1132 | | */ |
1133 | | static unsigned |
1134 | | fIHaveRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1135 | | |
1136 | | /** |
1137 | | * UnconfirmedPrivateTransfer-Request ::= SEQUENCE { |
1138 | | * vendorID [0] Unsigned, |
1139 | | * serviceNumber [1] Unsigned, |
1140 | | * serviceParameters [2] ABSTRACT-SYNTAX.&Type OPTIONAL |
1141 | | * } |
1142 | | * @param tvb the tv buffer of the current data |
1143 | | * @param pinfo the packet info of the current data |
1144 | | * @param tree the tree to append this item to |
1145 | | * @param offset the offset in the tvb |
1146 | | * @return modified offset |
1147 | | */ |
1148 | | static unsigned |
1149 | | fUnconfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1150 | | |
1151 | | /** |
1152 | | * UnconfirmedTextMessage-Request ::= SEQUENCE { |
1153 | | * textMessageSourceDevice [0] BACnetObjectIdentifier, |
1154 | | * messageClass [1] CHOICE { |
1155 | | * numeric [0] Unsigned, |
1156 | | * character [1] CharacterString |
1157 | | * } OPTIONAL, |
1158 | | * messagePriority [2] ENUMERATED { |
1159 | | * normal (0), |
1160 | | * urgent (1) |
1161 | | * }, |
1162 | | * message [3] CharacterString |
1163 | | * } |
1164 | | * @param tvb the tv buffer of the current data |
1165 | | * @param pinfo the packet info of the current data |
1166 | | * @param tree the tree to append this item to |
1167 | | * @param offset the offset in the tvb |
1168 | | * @return modified offset |
1169 | | */ |
1170 | | static unsigned |
1171 | | fUnconfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1172 | | |
1173 | | /** |
1174 | | * TimeSynchronization-Request ::= SEQUENCE { |
1175 | | * BACnetDateTime |
1176 | | * } |
1177 | | * @param tvb the tv buffer of the current data |
1178 | | * @param pinfo the packet info of the current data |
1179 | | * @param tree the tree to append this item to |
1180 | | * @param offset the offset in the tvb |
1181 | | * @return modified offset |
1182 | | */ |
1183 | | static unsigned |
1184 | | fTimeSynchronizationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1185 | | |
1186 | | /** |
1187 | | * UTCTimeSynchronization-Request ::= SEQUENCE { |
1188 | | * BACnetDateTime |
1189 | | * } |
1190 | | * @param tvb the tv buffer of the current data |
1191 | | * @param pinfo the packet info of the current data |
1192 | | * @param tree the tree to append this item to |
1193 | | * @param offset the offset in the tvb |
1194 | | * @return modified offset |
1195 | | */ |
1196 | | static unsigned |
1197 | | fUTCTimeSynchronizationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1198 | | |
1199 | | /** |
1200 | | * Who-Has-Request ::= SEQUENCE { |
1201 | | * limits SEQUENCE { |
1202 | | * deviceInstanceRangeLowLimit [0] Unsigned (0..4194303), |
1203 | | * deviceInstanceRangeHighLimit [1] Unsigned (0..4194303) |
1204 | | * } OPTIONAL, |
1205 | | * object CHOICE { |
1206 | | * objectIdentifier [2] BACnetObjectIdentifier, |
1207 | | * objectName [3] CharacterString |
1208 | | * } |
1209 | | * } |
1210 | | * @param tvb the tv buffer of the current data |
1211 | | * @param pinfo the packet info of the current data |
1212 | | * @param tree the tree to append this item to |
1213 | | * @param offset the offset in the tvb |
1214 | | * @return modified offset |
1215 | | */ |
1216 | | static unsigned |
1217 | | fWhoHas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1218 | | |
1219 | | /** |
1220 | | * Who-Is-Request ::= SEQUENCE { |
1221 | | * deviceInstanceRangeLowLimit [0] Unsigned (0..4194303) OPTIONAL, -- must be used as a pair, see 16.9, |
1222 | | * deviceInstanceRangeHighLimit [0] Unsigned (0..4194303) OPTIONAL, -- must be used as a pair, see 16.9, |
1223 | | * } |
1224 | | * @param tvb the tv buffer of the current data |
1225 | | * @param tree the tree to append this item to |
1226 | | * @param offset the offset in the tvb |
1227 | | * @return modified offset |
1228 | | */ |
1229 | | static unsigned |
1230 | | fWhoIsRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1231 | | |
1232 | | /** |
1233 | | * BACnet-Error ::= CHOICE { |
1234 | | * addListElement [8] ChangeList-Error, |
1235 | | * removeListElement [9] ChangeList-Error, |
1236 | | * writePropertyMultiple [16] WritePropertyMultiple-Error, |
1237 | | * confirmedPrivatTransfer [18] ConfirmedPrivateTransfer-Error, |
1238 | | * vtClose [22] VTClose-Error, |
1239 | | * readRange [26] ObjectAccessService-Error |
1240 | | * [default] Error |
1241 | | * } |
1242 | | * @param tvb the tv buffer of the current data |
1243 | | * @param pinfo the packet info of the current data |
1244 | | * @param tree the tree to append this item to |
1245 | | * @param offset the offset in the tvb |
1246 | | * @param service the service |
1247 | | * @return modified offset |
1248 | | */ |
1249 | | static unsigned |
1250 | | fBACnetError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, unsigned service); |
1251 | | |
1252 | | /** |
1253 | | * Dissect a BACnetError in a context tag |
1254 | | * |
1255 | | * @param tvb the tv buffer of the current data |
1256 | | * @param pinfo the packet info of the current data |
1257 | | * @param tree the tree to append this item to |
1258 | | * @param offset the offset in the tvb |
1259 | | * @return modified offset |
1260 | | */ |
1261 | | static unsigned fContextTaggedError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1262 | | |
1263 | | /** |
1264 | | * ChangeList-Error ::= SEQUENCE { |
1265 | | * errorType [0] Error, |
1266 | | * firstFailedElementNumber [1] Unsigned |
1267 | | * } |
1268 | | * } |
1269 | | * @param tvb the tv buffer of the current data |
1270 | | * @param pinfo the packet info of the current data |
1271 | | * @param tree the tree to append this item to |
1272 | | * @param offset the offset in the tvb |
1273 | | * @return modified offset |
1274 | | */ |
1275 | | static unsigned |
1276 | | fChangeListError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1277 | | |
1278 | | /** |
1279 | | * CreateObject-Error ::= SEQUENCE { |
1280 | | * errorType [0] Error, |
1281 | | * firstFailedElementNumber [1] Unsigned |
1282 | | * } |
1283 | | * } |
1284 | | * @param tvb the tv buffer of the current data |
1285 | | * @param pinfo the packet info of the current data |
1286 | | * @param tree the tree to append this item to |
1287 | | * @param offset the offset in the tvb |
1288 | | * @return modified offset |
1289 | | */ |
1290 | | static unsigned |
1291 | | fCreateObjectError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1292 | | |
1293 | | /** |
1294 | | * ConfirmedPrivateTransfer-Error ::= SEQUENCE { |
1295 | | * errorType [0] Error, |
1296 | | * vendorID [1] Unsigned, |
1297 | | * serviceNumber [2] Unsigned, |
1298 | | * errorParameters [3] ABSTRACT-SYNTAX.&Type OPTIONAL |
1299 | | * } |
1300 | | * } |
1301 | | * @param tvb the tv buffer of the current data |
1302 | | * @param pinfo the packet info of the current data |
1303 | | * @param tree the tree to append this item to |
1304 | | * @param offset the offset in the tvb |
1305 | | * @return modified offset |
1306 | | */ |
1307 | | static unsigned |
1308 | | fConfirmedPrivateTransferError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1309 | | |
1310 | | /** |
1311 | | * WritePropertyMultiple-Error ::= SEQUENCE { |
1312 | | * errorType [0] Error, |
1313 | | * firstFailedWriteAttempt [1] Unsigned |
1314 | | * } |
1315 | | * } |
1316 | | * @param tvb the tv buffer of the current data |
1317 | | * @param pinfo the packet info of the current data |
1318 | | * @param tree the tree to append this item to |
1319 | | * @param offset the offset in the tvb |
1320 | | * @return modified offset |
1321 | | */ |
1322 | | static unsigned |
1323 | | fWritePropertyMultipleError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1324 | | |
1325 | | /** |
1326 | | * VTClose-Error ::= SEQUENCE { |
1327 | | * errorType [0] Error, |
1328 | | * listOfVTSessionIdentifiers [1] SEQUENCE OF Unsigned8 OPTIONAL |
1329 | | * } |
1330 | | * } |
1331 | | * @param tvb the tv buffer of the current data |
1332 | | * @param pinfo the packet info of the current data |
1333 | | * @param tree the tree to append this item to |
1334 | | * @param offset the offset in the tvb |
1335 | | * @return modified offset |
1336 | | */ |
1337 | | static unsigned |
1338 | | fVTCloseError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1339 | | |
1340 | | /** |
1341 | | * BACnet Application Types chapter 20.2.1 |
1342 | | * @param tvb the tv buffer of the current data |
1343 | | * @param pinfo the packet info of the current data |
1344 | | * @param tree the tree to append this item to |
1345 | | * @param offset the offset in the tvb |
1346 | | * @param label the label of this item |
1347 | | * @return modified offset |
1348 | | */ |
1349 | | static unsigned |
1350 | | fApplicationTypes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label); |
1351 | | |
1352 | | /** |
1353 | | * BACnetActionCommand ::= SEQUENCE { |
1354 | | * deviceIdentifier [0] BACnetObjectIdentifier OPTIONAL, |
1355 | | * objectIdentifier [1] BACnetObjectIdentifier, |
1356 | | * propertyIdentifier [2] BACnetPropertyIdentifier, |
1357 | | * propertyArrayIndex [3] Unsigned OPTIONAL, -- used only with array datatype |
1358 | | * propertyValue [4] ABSTRACT-SYNTAX.&Type, |
1359 | | * priority [5] Unsigned (1..16) OPTIONAL, -- used only when property is commandable |
1360 | | * postDelay [6] Unsigned OPTIONAL, |
1361 | | * quitOnFailure [7] BOOLEAN, |
1362 | | * writeSuccessful [8] BOOLEAN |
1363 | | * } |
1364 | | * @param tvb the tv buffer of the current data |
1365 | | * @param pinfo the packet info of the current data |
1366 | | * @param tree the tree to append this item to |
1367 | | * @param offset the offset in the tvb |
1368 | | * @param tag_match the tag number |
1369 | | * @return modified offset |
1370 | | */ |
1371 | | static unsigned |
1372 | | fActionCommand(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, uint8_t tag_match); |
1373 | | |
1374 | | /** |
1375 | | * BACnetActionList ::= SEQUENCE { |
1376 | | * action [0] SEQUENCE of BACnetActionCommand |
1377 | | * } |
1378 | | * @param tvb the tv buffer of the current data |
1379 | | * @param pinfo the packet info of the current data |
1380 | | * @param tree the tree to append this item to |
1381 | | * @param offset the offset in the tvb |
1382 | | * @return modified offset |
1383 | | */ |
1384 | | static unsigned |
1385 | | fActionList(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1386 | | |
1387 | | /** BACnetAddress ::= SEQUENCE { |
1388 | | * network-number Unsigned16, -- A value 0 indicates the local network |
1389 | | * mac-address OCTET STRING -- A string of length 0 indicates a broadcast |
1390 | | * } |
1391 | | * @param tvb the tv buffer of the current data |
1392 | | * @param pinfo the packet info of the current data |
1393 | | * @param tree the tree to append this item to |
1394 | | * @param offset the offset in the tvb |
1395 | | * @return modified offset |
1396 | | */ |
1397 | | static unsigned |
1398 | | fAddress(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1399 | | |
1400 | | /** |
1401 | | * BACnetAddressBinding ::= SEQUENCE { |
1402 | | * deviceObjectID BACnetObjectIdentifier |
1403 | | * deviceAddress BacnetAddress |
1404 | | * } |
1405 | | * @param tvb the tv buffer of the current data |
1406 | | * @param pinfo the packet info of the current data |
1407 | | * @param tree the tree to append this item to |
1408 | | * @param offset the offset in the tvb |
1409 | | * @return modified offset |
1410 | | */ |
1411 | | static unsigned |
1412 | | fAddressBinding(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1413 | | |
1414 | | /** |
1415 | | * BACnetCalendarEntry ::= CHOICE { |
1416 | | * date [0] Date, |
1417 | | * dateRange [1] BACnetDateRange, |
1418 | | * weekNDay [2] BacnetWeekNday |
1419 | | * } |
1420 | | * @param tvb the tv buffer of the current data |
1421 | | * @param pinfo the packet info of the current data |
1422 | | * @param tree the tree to append this item to |
1423 | | * @param offset the offset in the tvb |
1424 | | * @return modified offset |
1425 | | */ |
1426 | | static unsigned |
1427 | | fCalendarEntry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1428 | | |
1429 | | /** |
1430 | | * BACnetClientCOV ::= CHOICE { |
1431 | | * real-increment REAL, |
1432 | | * default-increment NULL |
1433 | | * } |
1434 | | * @param tvb the tv buffer of the current data |
1435 | | * @param tree the tree to append this item to |
1436 | | * @param offset the offset in the tvb |
1437 | | * @return modified offset |
1438 | | */ |
1439 | | static unsigned |
1440 | | fClientCOV(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1441 | | |
1442 | | |
1443 | | /** |
1444 | | * BACnetDailySchedule ::= SEQUENCE { |
1445 | | * day-schedule [0] SENQUENCE OF BACnetTimeValue |
1446 | | * } |
1447 | | * @param tvb the tv buffer of the current data |
1448 | | * @param pinfo the packet info of the current data |
1449 | | * @param tree the tree to append this item to |
1450 | | * @param offset the offset in the tvb |
1451 | | * @return modified offset |
1452 | | */ |
1453 | | static unsigned |
1454 | | fDailySchedule(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1455 | | |
1456 | | /** |
1457 | | * BACnetHealth ::= SEQUENCE { |
1458 | | * timestamp [0] BACnetDateTime, |
1459 | | * result [1] Error, |
1460 | | * property [2] BACnetPropertyIdentifier OPTIONAL, |
1461 | | * details [3] CharacterString OPTIONAL |
1462 | | * } |
1463 | | * @param tvb the tv buffer of the current data |
1464 | | * @param pinfo the packet info of the current data |
1465 | | * @param tree the tree to append this item to |
1466 | | * @param offset the offset in the tvb |
1467 | | * @return modified offset |
1468 | | */ |
1469 | | static unsigned |
1470 | | fHealth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1471 | | |
1472 | | /** |
1473 | | * BACnetSCFailedConnectionRequest ::= SEQUENCE { |
1474 | | * timestamp [0] BACnetDateTime, |
1475 | | * peer-address [1] BACnetHostNPort, |
1476 | | * peer-vmac [2] OCTET STRING (SIZE(6)) |
1477 | | * peer-uuid [3] OCTET STRING (SIZE(16)) |
1478 | | * error [4] Error OPTIONAL |
1479 | | * error-details [5] CharacterString OPTIONAL |
1480 | | * } |
1481 | | * @param tvb the tv buffer of the current data |
1482 | | * @param pinfo the packet info of the current data |
1483 | | * @param tree the tree to append this item to |
1484 | | * @param offset the offset in the tvb |
1485 | | * @return modified offset |
1486 | | */ |
1487 | | static unsigned |
1488 | | fSCFailedConnectionRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1489 | | |
1490 | | /** |
1491 | | * BACnetSCDirectConnection ::= SEQUENCE { |
1492 | | * uri [0] CharacterString |
1493 | | * connection-state [1] BACnetSCConnectionState, |
1494 | | * connect-timestamp [2] BACnetDateTime, |
1495 | | * disconnect-timestamp [3] BACnetDateTime, |
1496 | | * peer-address [4] BACnetHostNPort, |
1497 | | * peer-vmac [5] OCTET STRING (SIZE(6)) |
1498 | | * peer-uuid [6] OCTET STRING (SIZE(16)) |
1499 | | * error [7] Error OPTIONAL |
1500 | | * error-details [8] CharacterString OPTIONAL |
1501 | | * } |
1502 | | * @param tvb the tv buffer of the current data |
1503 | | * @param pinfo the packet info of the current data |
1504 | | * @param tree the tree to append this item to |
1505 | | * @param offset the offset in the tvb |
1506 | | * @return modified offset |
1507 | | */ |
1508 | | static unsigned |
1509 | | fSCDirectConnection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1510 | | |
1511 | | /** |
1512 | | * BACnetSCHubConnection ::= SEQUENCE { |
1513 | | * connection-state [0] BACnetSCConnectionState, |
1514 | | * connect-timestamp [1] BACnetDateTime, |
1515 | | * disconnect-timestamp [2] BACnetDateTime, |
1516 | | * error [3] Error OPTIONAL |
1517 | | * error-details [4] CharacterString OPTIONAL |
1518 | | * } |
1519 | | * @param tvb the tv buffer of the current data |
1520 | | * @param pinfo the packet info of the current data |
1521 | | * @param tree the tree to append this item to |
1522 | | * @param offset the offset in the tvb |
1523 | | * @return modified offset |
1524 | | */ |
1525 | | static unsigned |
1526 | | fSCHubConnection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1527 | | |
1528 | | /** |
1529 | | * BACnetSCHubFunctionConnection ::= SEQUENCE { |
1530 | | * connection-state [0] BACnetSCConnectionState, |
1531 | | * connect-timestamp [1] BACnetDateTime, |
1532 | | * disconnect-timestamp [2] BACnetDateTime, |
1533 | | * peer-address [3] BACnetHostNPort, |
1534 | | * peer-vmac [4] OCTET STRING (SIZE(6)) |
1535 | | * peer-uuid [5] OCTET STRING (SIZE(16)) |
1536 | | * error [6] Error OPTIONAL |
1537 | | * error-details [7] CharacterString OPTIONAL |
1538 | | * } |
1539 | | * @param tvb the tv buffer of the current data |
1540 | | * @param pinfo the packet info of the current data |
1541 | | * @param tree the tree to append this item to |
1542 | | * @param offset the offset in the tvb |
1543 | | * @return modified offset |
1544 | | */ |
1545 | | static unsigned |
1546 | | fSCHubFunctionConnection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1547 | | |
1548 | | /** |
1549 | | * BACnetWeeklySchedule ::= SEQUENCE { |
1550 | | * week-schedule SENQUENCE SIZE (7) OF BACnetDailySchedule |
1551 | | * } |
1552 | | * @param tvb the tv buffer of the current data |
1553 | | * @param pinfo the packet info of the current data |
1554 | | * @param tree the tree to append this item to |
1555 | | * @param offset the offset in the tvb |
1556 | | * @return modified offset |
1557 | | */ |
1558 | | static unsigned |
1559 | | fWeeklySchedule(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1560 | | |
1561 | | /** |
1562 | | * BACnetDateRange ::= SEQUENCE { |
1563 | | * StartDate Date, |
1564 | | * EndDate Date |
1565 | | * } |
1566 | | * @param tvb the tv buffer of the current data |
1567 | | * @param pinfo the packet info of the current data |
1568 | | * @param tree the tree to append this item to |
1569 | | * @param offset the offset in the tvb |
1570 | | * @return modified offset |
1571 | | */ |
1572 | | static unsigned |
1573 | | fDateRange(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1574 | | |
1575 | | /** |
1576 | | * BACnetDateTime ::= SEQUENCE { |
1577 | | * date Date, |
1578 | | * time Time |
1579 | | * } |
1580 | | * @param tvb the tv buffer of the current data |
1581 | | * @param pinfo the packet info of the current data |
1582 | | * @param tree the tree to append this item to |
1583 | | * @param offset the offset in the tvb |
1584 | | * @param label the label of this item |
1585 | | * @return modified offset |
1586 | | */ |
1587 | | static unsigned |
1588 | | fDateTime(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label); |
1589 | | |
1590 | | /** |
1591 | | * BACnetDestination ::= SEQUENCE { |
1592 | | * validDays BACnetDaysOfWeek, |
1593 | | * fromTime Time, |
1594 | | * toTime Time, |
1595 | | * recipient BACnetRecipient, |
1596 | | * processIdentifier Unsigned32, |
1597 | | * issueConfirmedNotifications BOOLEAN, |
1598 | | * transitions BACnetEventTransitionBits |
1599 | | * } |
1600 | | * @param tvb the tv buffer of the current data |
1601 | | * @param pinfo the packet info of the current data |
1602 | | * @param tree the tree to append this item to |
1603 | | * @param offset the offset in the tvb |
1604 | | * @return modified offset |
1605 | | */ |
1606 | | static unsigned |
1607 | | fDestination(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1608 | | |
1609 | | /** |
1610 | | * BACnetDeviceObjectPropertyReference ::= SEQUENCE { |
1611 | | * objectIdentifier [0] BACnetObjectIdentifier, |
1612 | | * propertyIdentifier [1] BACnetPropertyIdentifier, |
1613 | | * propertyArrayIndex [2] Unsigned OPTIONAL, |
1614 | | * deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL |
1615 | | * } |
1616 | | * @param tvb the tv buffer of the current data |
1617 | | * @param pinfo the packet info of the current data |
1618 | | * @param tree the tree to append this item to |
1619 | | * @param offset the offset in the tvb |
1620 | | * @return modified offset |
1621 | | */ |
1622 | | static unsigned |
1623 | | fDeviceObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1624 | | |
1625 | | /** |
1626 | | * BACnetObjectPropertyReference ::= SEQUENCE { |
1627 | | * objectIdentifier [0] BACnetObjectIdentifier, |
1628 | | * propertyIdentifier [1] BACnetPropertyIdentifier, |
1629 | | * propertyArrayIndex [2] Unsigned OPTIONAL, |
1630 | | * } |
1631 | | * @param tvb the tv buffer of the current data |
1632 | | * @param pinfo the packet info of the current data |
1633 | | * @param tree the tree to append this item to |
1634 | | * @param offset the offset in the tvb |
1635 | | * @return modified offset |
1636 | | */ |
1637 | | static unsigned |
1638 | | fObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1639 | | |
1640 | | /** |
1641 | | * BACnetDeviceObjectReference ::= SEQUENCE { |
1642 | | * deviceIdentifier [0] BACnetObjectIdentifier OPTIONAL, |
1643 | | * objectIdentifier [1] BACnetObjectIdentifier |
1644 | | * } |
1645 | | * @param tvb the tv buffer of the current data |
1646 | | * @param pinfo the packet info of the current data |
1647 | | * @param tree the tree to append this item to |
1648 | | * @param offset the offset in the tvb |
1649 | | * @return modified offset |
1650 | | */ |
1651 | | static unsigned |
1652 | | fDeviceObjectReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1653 | | |
1654 | | /** |
1655 | | * BACnetEventParameter ::= CHOICE { |
1656 | | * change-of-bitstring [0] SEQUENCE { |
1657 | | * time-delay [0] Unsigned, |
1658 | | * bitmask [1] BIT STRING, |
1659 | | * list-of-bitstring-values [2] SEQUENCE OF BIT STRING |
1660 | | * }, |
1661 | | * change-of-state [1] SEQUENCE { |
1662 | | * time-delay [0] Unsigned, |
1663 | | * list-of-values [1] SEQUENCE OF BACnetPropertyStates |
1664 | | * }, |
1665 | | * change-of-value [2] SEQUENCE { |
1666 | | * time-delay [0] Unsigned, |
1667 | | * cov-criteria [1] CHOICE { |
1668 | | * bitmask [0] BIT STRING, |
1669 | | * referenced-property-increment [1] REAL |
1670 | | * } |
1671 | | * }, |
1672 | | * command-failure [3] SEQUENCE { |
1673 | | * time-delay [0] Unsigned, |
1674 | | * feedback-property-reference [1] BACnetDeviceObjectPropertyReference |
1675 | | * }, |
1676 | | * floating-limit [4] SEQUENCE { |
1677 | | * time-delay [0] Unsigned, |
1678 | | * setpoint-reference [1] BACnetDeviceObjectPropertyReference, |
1679 | | * low-diff-limit [2] REAL, |
1680 | | * high-diff-limit [3] REAL, |
1681 | | * deadband [4] REAL |
1682 | | * }, |
1683 | | * out-of-range [5] SEQUENCE { |
1684 | | * time-delay [0] Unsigned, |
1685 | | * low-limit [1] REAL, |
1686 | | * high-limit [2] REAL, |
1687 | | * deadband [3] REAL |
1688 | | * }, |
1689 | | * -- context tag 7 is deprecated |
1690 | | * change-of-life-safety [8] SEQUENCE { |
1691 | | * time-delay [0] Unsigned, |
1692 | | * list-of-life-safety-alarm-values [1] SEQUENCE OF BACnetLifeSafetyState, |
1693 | | * list-of-alarm-values [2] SEQUENCE OF BACnetLifeSafetyState, |
1694 | | * mode-property-reference [3] BACnetDeviceObjectPropertyReference |
1695 | | * }, |
1696 | | * extended [9] SEQUENCE { |
1697 | | * vendor-id [0] Unsigned16, |
1698 | | * extended-event-type [1] Unsigned, |
1699 | | * parameters [2] SEQUENCE OF CHOICE { |
1700 | | * null NULL, |
1701 | | * real REAL, |
1702 | | * integer Unsigned, |
1703 | | * boolean BOOLEAN, |
1704 | | * double Double, |
1705 | | * octet OCTET STRING, |
1706 | | * bitstring BIT STRING, |
1707 | | * enum ENUMERATED, |
1708 | | * reference [0] BACnetDeviceObjectPropertyReference |
1709 | | * } |
1710 | | * }, |
1711 | | * buffer-ready [10] SEQUENCE { |
1712 | | * notification-threshold [0] Unsigned, |
1713 | | * previous-notification-count [1] Unsigned32 |
1714 | | * }, |
1715 | | * unsigned-range [11] SEQUENCE { |
1716 | | * time-delay [0] Unsigned, |
1717 | | * low-limit [1] Unsigned, |
1718 | | * high-limit [2] Unsigned, |
1719 | | * } |
1720 | | * -- context tag 12 is reserved for future addenda |
1721 | | * access-event [13] SEQUENCE { |
1722 | | * list-of-access-events [0] SEQUENCE OF BACnetAccessEvent, |
1723 | | * access-event-time-reference [1] BACnetDeviceObjectPropertyReference |
1724 | | * } |
1725 | | * double-out-of-range [14] SEQUENCE { |
1726 | | * time-delay [0] Unsigned, |
1727 | | * low-limit [1] Double, |
1728 | | * high-limit [2] Double, |
1729 | | * deadband [3] Double |
1730 | | * } |
1731 | | * signed-out-of-range [15] SEQUENCE { |
1732 | | * time-delay [0] Unsigned, |
1733 | | * low-limit [1] INTEGER, |
1734 | | * high-limit [2] INTEGER, |
1735 | | * deadband [3] Unsigned |
1736 | | * } |
1737 | | * unsigned-out-of-range [16] SEQUENCE { |
1738 | | * time-delay [0] Unsigned, |
1739 | | * low-limit [1] Unsigned, |
1740 | | * high-limit [2] Unsigned, |
1741 | | * deadband [3] Unsigned |
1742 | | * } |
1743 | | * change-of-characterstring [17] SEQUENCE { |
1744 | | * time-delay [0] Unsigned, |
1745 | | * list-of-alarm-values [1] SEQUENCE OF CharacterString, |
1746 | | * } |
1747 | | * change-of-status-flags [18] SEQUENCE { |
1748 | | * time-delay [0] Unsigned, |
1749 | | * selected-flags [1] BACnetStatusFlags |
1750 | | * } |
1751 | | * } |
1752 | | * @param tvb the tv buffer of the current data |
1753 | | * @param tree the tree to append this item to |
1754 | | * @param offset the offset in the tvb |
1755 | | * @return modified offset |
1756 | | */ |
1757 | | static unsigned |
1758 | | fEventParameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1759 | | |
1760 | | |
1761 | | |
1762 | | /** |
1763 | | * BACnetLogRecord ::= SEQUENCE { |
1764 | | * timestamp [0] BACnetDateTime, |
1765 | | * logDatum [1] CHOICE { |
1766 | | * log-status [0] BACnetLogStatus, |
1767 | | * boolean-value [1] BOOLEAN, |
1768 | | * real-value [2] REAL, |
1769 | | * enum-value [3] ENUMERATED, -- Optionally limited to 32 bits |
1770 | | * unsigned-value [4] Unsigned, -- Optionally limited to 32 bits |
1771 | | * signed-value [5] INTEGER, -- Optionally limited to 32 bits |
1772 | | * bitstring-value [6] BIT STRING, -- Optionally limited to 32 bits |
1773 | | * null-value [7] NULL, |
1774 | | * failure [8] Error, |
1775 | | * time-change [9] REAL, |
1776 | | * any-value [10] ABSTRACT-SYNTAX.&Type -- Optional |
1777 | | * } |
1778 | | * statusFlags [2] BACnetStatusFlags OPTIONAL |
1779 | | * } |
1780 | | * @param tvb the tv buffer of the current data |
1781 | | * @param pinfo the packet info of the current data |
1782 | | * @param tree the tree to append this item to |
1783 | | * @param offset the offset in the tvb |
1784 | | * @return modified offset |
1785 | | */ |
1786 | | static unsigned |
1787 | | fLogRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1788 | | |
1789 | | /** |
1790 | | * BACnetEventLogRecord ::= SEQUENCE { |
1791 | | * timestamp [0] BACnetDateTime, |
1792 | | * logDatum [1] CHOICE { |
1793 | | * log-status [0] BACnetLogStatus, |
1794 | | * notification [1] ConfirmedEventNotification-Request, |
1795 | | * time-change [2] REAL, |
1796 | | * } |
1797 | | * } |
1798 | | * @param tvb the tv buffer of the current data |
1799 | | * @param pinfo the packet info of the current data |
1800 | | * @param tree the tree to append this item to |
1801 | | * @param offset the offset in the tvb |
1802 | | * @return modified offset |
1803 | | */ |
1804 | | static unsigned |
1805 | | fEventLogRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1806 | | |
1807 | | static unsigned |
1808 | | fLogMultipleRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1809 | | |
1810 | | /** |
1811 | | * BACnetNotificationParameters ::= CHOICE { |
1812 | | * change-of-bitstring [0] SEQUENCE { |
1813 | | * referenced-bitstring [0] BIT STRING, |
1814 | | * status-flags [1] BACnetStatusFlags |
1815 | | * }, |
1816 | | * change-of-state [1] SEQUENCE { |
1817 | | * new-state [0] BACnetPropertyStatus, |
1818 | | * status-flags [1] BACnetStatusFlags |
1819 | | * }, |
1820 | | * change-of-value [2] SEQUENCE { |
1821 | | * new-value [0] CHOICE { |
1822 | | * changed-bits [0] BIT STRING, |
1823 | | * changed-value [1] REAL |
1824 | | * }, |
1825 | | * status-flags [1] BACnetStatusFlags |
1826 | | * }, |
1827 | | * command-failure [3] SEQUENCE { |
1828 | | * command-value [0] ABSTRACT-SYNTAX.&Type, -- depends on ref property |
1829 | | * status-flags [1] BACnetStatusFlags |
1830 | | * feedback-value [2] ABSTRACT-SYNTAX.&Type -- depends on ref property |
1831 | | * }, |
1832 | | * floating-limit [4] SEQUENCE { |
1833 | | * reference-value [0] REAL, |
1834 | | * status-flags [1] BACnetStatusFlags |
1835 | | * setpoint-value [2] REAL, |
1836 | | * error-limit [3] REAL |
1837 | | * }, |
1838 | | * out-of-range [5] SEQUENCE { |
1839 | | * exceeding-value [0] REAL, |
1840 | | * status-flags [1] BACnetStatusFlags |
1841 | | * deadband [2] REAL, |
1842 | | * exceeded-limit [3] REAL |
1843 | | * }, |
1844 | | * complex-event-type [6] SEQUENCE OF BACnetPropertyValue, |
1845 | | * -- complex tag 7 is deprecated |
1846 | | * change-of-life-safety [8] SEQUENCE { |
1847 | | * new-state [0] BACnetLifeSafetyState, |
1848 | | * new-mode [1] BACnetLifeSafetyState |
1849 | | * status-flags [2] BACnetStatusFlags, |
1850 | | * operation-expected [3] BACnetLifeSafetyOperation |
1851 | | * }, |
1852 | | * extended [9] SEQUENCE { |
1853 | | * vendor-id [0] Unsigned16, |
1854 | | * extended-event-type [1] Unsigned, |
1855 | | * parameters [2] SEQUENCE OF CHOICE { |
1856 | | * null NULL, |
1857 | | * real REAL, |
1858 | | * integer Unsigned, |
1859 | | * boolean BOOLEAN, |
1860 | | * double Double, |
1861 | | * octet OCTET STRING, |
1862 | | * bitstring BIT STRING, |
1863 | | * enum ENUMERATED, |
1864 | | * propertyValue [0] BACnetDeviceObjectPropertyValue |
1865 | | * } |
1866 | | * }, |
1867 | | * buffer-ready [10] SEQUENCE { |
1868 | | * buffer-property [0] BACnetDeviceObjectPropertyReference, |
1869 | | * previous-notification[1] Unsigned32, |
1870 | | * current-notification [2] BACneUnsigned32tDateTime |
1871 | | * }, |
1872 | | * unsigned-range [11] SEQUENCE { |
1873 | | * exceeding-value [0] Unsigned, |
1874 | | * status-flags [1] BACnetStatusFlags, |
1875 | | * exceeded-limit [2] Unsigned |
1876 | | * }, |
1877 | | * -- context tag 12 is reserved for future addenda |
1878 | | * access-event [13] SEQUENCE { |
1879 | | * access-event [0] BACnetAccessEvent, |
1880 | | * status-flags [1] BACnetStatusFlags, |
1881 | | * access-event-tag [2] Unsigned, |
1882 | | * access-event-time [3] BACnetTimeStamp, |
1883 | | * access-credential [4] BACnetDeviceObjectReference, |
1884 | | * authentication-factor [5] BACnetAuthenticationFactor OPTIONAL |
1885 | | * }, |
1886 | | * double-out-of-range [14] SEQUENCE { |
1887 | | * exceeding-value [0] Double, |
1888 | | * status-flags [1] BACnetStatusFlags |
1889 | | * deadband [2] Double, |
1890 | | * exceeded-limit [3] Double |
1891 | | * }, |
1892 | | * signed-out-of-range [15] SEQUENCE { |
1893 | | * exceeding-value [0] INTEGER, |
1894 | | * status-flags [1] BACnetStatusFlags |
1895 | | * deadband [2] Unsigned, |
1896 | | * exceeded-limit [3] INTEGER |
1897 | | * }, |
1898 | | * unsigned-out-of-range [16] SEQUENCE { |
1899 | | * exceeding-value [0] Unsigned, |
1900 | | * status-flags [1] BACnetStatusFlags |
1901 | | * deadband [2] Unsigned, |
1902 | | * exceeded-limit [3] Unsigned |
1903 | | * }, |
1904 | | * change-of-characterstring [17] SEQUENCE { |
1905 | | * changed-value [0] CharacterString, |
1906 | | * status-flags [1] BACnetStatusFlags |
1907 | | * alarm-value [2] CharacterString |
1908 | | * }, |
1909 | | * change-of-status-flags [18] SEQUENCE { |
1910 | | * present-value [0] ABSTRACT-SYNTAX.&Type OPTIONAL, |
1911 | | * -- depends on referenced property |
1912 | | * referenced-flags [1] BACnetStatusFlags |
1913 | | * }, |
1914 | | * } |
1915 | | * @param tvb the tv buffer of the current data |
1916 | | * @param pinfo the packet info of the current data |
1917 | | * @param tree the tree to append this item to |
1918 | | * @param offset the offset in the tvb |
1919 | | * @return modified offset |
1920 | | */ |
1921 | | static unsigned |
1922 | | fNotificationParameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1923 | | |
1924 | | /** |
1925 | | * BACnetObjectPropertyReference ::= SEQUENCE { |
1926 | | * objectIdentifier [0] BACnetObjectIdentifier, |
1927 | | * propertyIdentifier [1] BACnetPropertyIdentifier, |
1928 | | * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype |
1929 | | * } |
1930 | | * @param tvb the tv buffer of the current data |
1931 | | * @param pinfo the packet info of the current data |
1932 | | * @param tree the tree to append this item to |
1933 | | * @param offset the offset in the tvb |
1934 | | * @return modified offset |
1935 | | */ |
1936 | | static unsigned |
1937 | | fBACnetObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1938 | | |
1939 | | #if 0 |
1940 | | /** |
1941 | | * BACnetObjectPropertyValue ::= SEQUENCE { |
1942 | | * objectIdentifier [0] BACnetObjectIdentifier, |
1943 | | * propertyIdentifier [1] BACnetPropertyIdentifier, |
1944 | | * propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype |
1945 | | * -- if omitted with an array the entire array is referenced |
1946 | | * value [3] ABSTRACT-SYNTAX.&Type, --any datatype appropriate for the specified property |
1947 | | * priority [4] Unsigned (1..16) OPTIONAL |
1948 | | * } |
1949 | | * @param tvb the tv buffer of the current data |
1950 | | * @param tree the tree to append this item to |
1951 | | * @param offset the offset in the tvb |
1952 | | * @return modified offset |
1953 | | */ |
1954 | | static unsigned |
1955 | | fObjectPropertyValue(tvbuff_t *tvb, proto_tree *tree, unsigned offset); |
1956 | | #endif |
1957 | | |
1958 | | /** |
1959 | | * BACnetPriorityArray ::= SEQUENCE SIZE (16) OF BACnetPriorityValue |
1960 | | * @param tvb the tv buffer of the current data |
1961 | | * @param pinfo the packet info of the current data |
1962 | | * @param tree the tree to append this item to |
1963 | | * @param offset the offset in the tvb |
1964 | | * @return modified offset |
1965 | | */ |
1966 | | static unsigned |
1967 | | fPriorityArray(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1968 | | |
1969 | | static unsigned |
1970 | | fPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, uint8_t tagoffset, uint8_t list); |
1971 | | |
1972 | | /** |
1973 | | * BACnetPropertyReference ::= SEQUENCE { |
1974 | | * propertyIdentifier [0] BACnetPropertyIdentifier, |
1975 | | * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatype |
1976 | | * } |
1977 | | * @param tvb the tv buffer of the current data |
1978 | | * @param pinfo the packet info of the current data |
1979 | | * @param tree the tree to append this item to |
1980 | | * @param offset the offset in the tvb |
1981 | | * @return modified offset |
1982 | | */ |
1983 | | static unsigned |
1984 | | fBACnetPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, uint8_t list); |
1985 | | |
1986 | | static unsigned |
1987 | | fLOPR(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1988 | | |
1989 | | static unsigned |
1990 | | fRestartReason(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
1991 | | |
1992 | | /** |
1993 | | * BACnetPropertyValue ::= SEQUENCE { |
1994 | | * PropertyIdentifier [0] BACnetPropertyIdentifier, |
1995 | | * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatypes |
1996 | | * -- if omitted with an array the entire array is referenced |
1997 | | * value [2] ABSTRACT-SYNTAX.&Type, -- any datatype appropriate for the specified property |
1998 | | * priority [3] Unsigned (1..16) OPTIONAL -- used only when property is commandable |
1999 | | * } |
2000 | | * @param tvb the tv buffer of the current data |
2001 | | * @param pinfo the packet info of the current data |
2002 | | * @param tree the tree to append this item to |
2003 | | * @param offset the offset in the tvb |
2004 | | * @return modified offset |
2005 | | */ |
2006 | | static unsigned |
2007 | | fBACnetPropertyValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2008 | | |
2009 | | static unsigned |
2010 | | fPropertyValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, uint8_t tagoffset); |
2011 | | |
2012 | | /** |
2013 | | * BACnet Application PDUs chapter 21 |
2014 | | * BACnetRecipient::= CHOICE { |
2015 | | * device [0] BACnetObjectIdentifier |
2016 | | * address [1] BACnetAddress |
2017 | | * } |
2018 | | * @param tvb the tv buffer of the current data |
2019 | | * @param pinfo the packet info of the current data |
2020 | | * @param tree the tree to append this item to |
2021 | | * @param offset the offset in the tvb |
2022 | | * @return modified offset |
2023 | | */ |
2024 | | static unsigned |
2025 | | fRecipient(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2026 | | |
2027 | | /** |
2028 | | * BACnet Application PDUs chapter 21 |
2029 | | * BACnetRecipientProcess::= SEQUENCE { |
2030 | | * recipient [0] BACnetRecipient |
2031 | | * processID [1] Unsigned32 |
2032 | | * } |
2033 | | * @param tvb the tv buffer of the current data |
2034 | | * @param pinfo the packet info of the current data |
2035 | | * @param tree the tree to append this item to |
2036 | | * @param offset the offset in the tvb |
2037 | | * @return modified offset |
2038 | | */ |
2039 | | static unsigned |
2040 | | fRecipientProcess(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2041 | | |
2042 | | static unsigned |
2043 | | fCOVSubscription(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2044 | | |
2045 | | #if 0 |
2046 | | /** |
2047 | | * BACnetSessionKey ::= SEQUENCE { |
2048 | | * sessionKey OCTET STRING (SIZE(8)), -- 56 bits for key, 8 bits for checksum |
2049 | | * peerAddress BACnetAddress |
2050 | | * } |
2051 | | * @param tvb the tv buffer of the current data |
2052 | | * @param tree the tree to append this item to |
2053 | | * @param offset the offset in the tvb |
2054 | | * @return modified offset |
2055 | | * @todo check if checksum is displayed correctly |
2056 | | */ |
2057 | | static unsigned |
2058 | | fSessionKey(tvbuff_t *tvb, proto_tree *tree, unsigned offset); |
2059 | | #endif |
2060 | | |
2061 | | /** |
2062 | | * BACnetSpecialEvent ::= SEQUENCE { |
2063 | | * period CHOICE { |
2064 | | * calendarEntry [0] BACnetCalendarEntry, |
2065 | | * calendarReference [1] BACnetObjectIdentifier |
2066 | | * }, |
2067 | | * listOfTimeValues [2] SEQUENCE OF BACnetTimeValue, |
2068 | | * eventPriority [3] Unsigned (1..16) |
2069 | | * } |
2070 | | * @param tvb the tv buffer of the current data |
2071 | | * @param pinfo the packet info of the current data |
2072 | | * @param tree the tree to append this item to |
2073 | | * @param offset the offset in the tvb |
2074 | | * @return modified offset |
2075 | | */ |
2076 | | static unsigned |
2077 | | fSpecialEvent(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2078 | | |
2079 | | /** |
2080 | | * BACnetTimeStamp ::= CHOICE { |
2081 | | * time [0] Time, |
2082 | | * sequenceNumber [1] Unsigned (0..65535), |
2083 | | * dateTime [2] BACnetDateTime |
2084 | | * } |
2085 | | * @param tvb the tv buffer of the current data |
2086 | | * @param pinfo the packet info of the current data |
2087 | | * @param tree the tree to append this item to |
2088 | | * @param offset the offset in the tvb |
2089 | | * @param label the label of this item |
2090 | | * @return modified offset |
2091 | | */ |
2092 | | static unsigned |
2093 | | fTimeStamp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label); |
2094 | | |
2095 | | static unsigned |
2096 | | fEventTimeStamps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2097 | | |
2098 | | /** |
2099 | | * BACnetTimeValue ::= SEQUENCE { |
2100 | | * time Time, |
2101 | | * value ABSTRACT-SYNTAX.&Type -- any primitive datatype, complex types cannot be decoded |
2102 | | * } |
2103 | | * @param tvb the tv buffer of the current data |
2104 | | * @param pinfo the packet info of the current data |
2105 | | * @param tree the tree to append this item to |
2106 | | * @param offset the offset in the tvb |
2107 | | * @return modified offset |
2108 | | */ |
2109 | | static unsigned |
2110 | | fTimeValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2111 | | |
2112 | | #if 0 |
2113 | | /** |
2114 | | * BACnetVTSession ::= SEQUENCE { |
2115 | | * local-vtSessionID Unsigned8, |
2116 | | * remote-vtSessionID Unsigned8, |
2117 | | * remote-vtAddress BACnetAddress |
2118 | | * } |
2119 | | * @param tvb the tv buffer of the current data |
2120 | | * @param tree the tree to append this item to |
2121 | | * @param offset the offset in the tvb |
2122 | | * @return modified offset |
2123 | | */ |
2124 | | static unsigned |
2125 | | fVTSession(tvbuff_t *tvb, proto_tree *tree, unsigned offset); |
2126 | | #endif |
2127 | | |
2128 | | /** |
2129 | | * BACnetWeekNDay ::= OCTET STRING (SIZE (3)) |
2130 | | * -- first octet month (1..12) January = 1, X'FF' = any month |
2131 | | * -- second octet weekOfMonth where: 1 = days numbered 1-7 |
2132 | | * -- 2 = days numbered 8-14 |
2133 | | * -- 3 = days numbered 15-21 |
2134 | | * -- 4 = days numbered 22-28 |
2135 | | * -- 5 = days numbered 29-31 |
2136 | | * -- 6 = last 7 days of this month |
2137 | | * -- X'FF' = any week of this month |
2138 | | * -- third octet dayOfWeek (1..7) where 1 = Monday |
2139 | | * -- 7 = Sunday |
2140 | | * -- X'FF' = any day of week |
2141 | | * @param tvb the tv buffer of the current data |
2142 | | * @param pinfo the packet info of the current data |
2143 | | * @param tree the tree to append this item to |
2144 | | * @param offset the offset in the tvb |
2145 | | * @return modified offset |
2146 | | */ |
2147 | | static unsigned |
2148 | | fWeekNDay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2149 | | |
2150 | | /** |
2151 | | * ReadAccessResult ::= SEQUENCE { |
2152 | | * objectIdentifier [0] BACnetObjectIdentifier, |
2153 | | * listOfResults [1] SEQUENCE OF SEQUENCE { |
2154 | | * propertyIdentifier [2] BACnetPropertyIdentifier, |
2155 | | * propertyArrayIndex [3] Unsigned OPTIONAL, -- used only with array datatype if omitted with an array the entire array is referenced |
2156 | | * readResult CHOICE { |
2157 | | * propertyValue [4] ABSTRACT-SYNTAX.&Type, |
2158 | | * propertyAccessError [5] Error |
2159 | | * } |
2160 | | * } OPTIONAL |
2161 | | * } |
2162 | | * @param tvb the tv buffer of the current data |
2163 | | * @param pinfo the packet info of the current data |
2164 | | * @param tree the tree to append this item to |
2165 | | * @param offset the offset in the tvb |
2166 | | * @return modified offset |
2167 | | */ |
2168 | | static unsigned |
2169 | | fReadAccessResult(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2170 | | |
2171 | | /** |
2172 | | * ReadAccessSpecification ::= SEQUENCE { |
2173 | | * objectIdentifier [0] BACnetObjectIdentifier, |
2174 | | * listOfPropertyReferences [1] SEQUENCE OF BACnetPropertyReference |
2175 | | * } |
2176 | | * @param tvb the tv buffer of the current data |
2177 | | * @param pinfo the packet info of the current data |
2178 | | * @param subtree the subtree to append this item to |
2179 | | * @param offset the offset in the tvb |
2180 | | * @return modified offset |
2181 | | */ |
2182 | | static unsigned |
2183 | | fReadAccessSpecification(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, unsigned offset); |
2184 | | |
2185 | | /** |
2186 | | * WriteAccessSpecification ::= SEQUENCE { |
2187 | | * objectIdentifier [0] BACnetObjectIdentifier, |
2188 | | * listOfProperty [1] SEQUENCE OF BACnetPropertyValue |
2189 | | * } |
2190 | | * @param tvb the tv buffer of the current data |
2191 | | * @param pinfo the packet info of the current data |
2192 | | * @param subtree the sub tree to append this item to |
2193 | | * @param offset the offset in the tvb |
2194 | | * @return modified offset |
2195 | | */ |
2196 | | static unsigned |
2197 | | fWriteAccessSpecification(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, unsigned offset); |
2198 | | |
2199 | | |
2200 | | /********************************************************* Helper functions *******************************************/ |
2201 | | |
2202 | | /** |
2203 | | * extracts the tag number from the tag header. |
2204 | | * @param tvb the tv buffer of the current data "TestyVirtualBuffer" |
2205 | | * @param offset the offset in the tvb in actual tvb |
2206 | | * @return Tag Number corresponding to BACnet 20.2.1.2 Tag Number |
2207 | | */ |
2208 | | static unsigned |
2209 | | fTagNo(tvbuff_t *tvb, unsigned offset); |
2210 | | |
2211 | | /** |
2212 | | * splits Tag Header corresponding to 20.2.1 General Rules For BACnet Tags |
2213 | | * @param tvb the tv buffer of the current data = "TestyVirtualBuffer" |
2214 | | * @param pinfo the packet info of the current data = packet info |
2215 | | * @param offset the offset in the tvb = offset in actual tvb |
2216 | | * @return tag_no BACnet 20.2.1.2 Tag Number |
2217 | | * @return class_tag BACnet 20.2.1.1 Class |
2218 | | * @return lvt BACnet 20.2.1.3 Length/Value/Type |
2219 | | * @return offs = length of this header |
2220 | | */ |
2221 | | |
2222 | | static unsigned |
2223 | | fTagHeader(tvbuff_t *tvb, packet_info *pinfo, unsigned offset, uint8_t *tag_no, uint8_t* class_tag, uint32_t *lvt); |
2224 | | |
2225 | | |
2226 | | /** |
2227 | | * adds processID with max 32Bit unsigned Integer Value to tree |
2228 | | * @param tvb the tv buffer of the current data |
2229 | | * @param pinfo the packet info of the current data |
2230 | | * @param tree the tree to append this item to |
2231 | | * @param offset the offset in the tvb |
2232 | | * @return modified offset |
2233 | | */ |
2234 | | static unsigned |
2235 | | fProcessId(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2236 | | |
2237 | | /** |
2238 | | * adds present value to the tree |
2239 | | * @param tvb the tv buffer of the current data |
2240 | | * @param pinfo the packet info of the current data |
2241 | | * @param tree the tree to append this item to |
2242 | | * @param offset the offset in the tvb |
2243 | | * @param vs enum of string values when applicable |
2244 | | * @param split_val enum index |
2245 | | * @param type present value datatype enum |
2246 | | * @return modified offset |
2247 | | */ |
2248 | | static unsigned |
2249 | | fPresentValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const value_string *vs, uint32_t split_val, BacappPresentValueType type); |
2250 | | |
2251 | | /** |
2252 | | * adds event type to the tree |
2253 | | * @param tvb the tv buffer of the current data |
2254 | | * @param pinfo the packet info of the current data |
2255 | | * @param tree the tree to append this item to |
2256 | | * @param offset the offset in the tvb |
2257 | | * @return modified offset |
2258 | | */ |
2259 | | static unsigned |
2260 | | fEventType(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2261 | | |
2262 | | /** |
2263 | | * adds notify type to the tree |
2264 | | * @param tvb the tv buffer of the current data |
2265 | | * @param pinfo the packet info of the current data |
2266 | | * @param tree the tree to append this item to |
2267 | | * @param offset the offset in the tvb |
2268 | | * @return modified offset |
2269 | | */ |
2270 | | static unsigned |
2271 | | fNotifyType(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2272 | | |
2273 | | /** |
2274 | | * adds next_state with max 32Bit unsigned Integer Value to tree |
2275 | | * @param tvb the tv buffer of the current data |
2276 | | * @param pinfo the packet info of the current data |
2277 | | * @param tree the tree to append this item to |
2278 | | * @param offset the offset in the tvb |
2279 | | * @return modified offset |
2280 | | */ |
2281 | | static unsigned |
2282 | | fToState(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2283 | | |
2284 | | /** |
2285 | | * adds from_state with max 32Bit unsigned Integer Value to tree |
2286 | | * @param tvb the tv buffer of the current data |
2287 | | * @param pinfo the packet info of the current data |
2288 | | * @param tree the tree to append this item to |
2289 | | * @param offset the offset in the tvb |
2290 | | * @return modified offset |
2291 | | */ |
2292 | | static unsigned |
2293 | | fFromState(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2294 | | |
2295 | | /** |
2296 | | * adds object_name string value to tree |
2297 | | * @param tvb the tv buffer of the current data |
2298 | | * @param pinfo the packet info of the current data |
2299 | | * @param tree the tree to append this item to |
2300 | | * @param offset the offset in the tvb |
2301 | | * @return modified offset |
2302 | | */ |
2303 | | static unsigned |
2304 | | fObjectName(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2305 | | |
2306 | | /** |
2307 | | * wrapper function for fCharacterStringBase |
2308 | | * @param tvb the tv buffer of the current data |
2309 | | * @param pinfo the packet info of the current data |
2310 | | * @param tree the tree to append this item to |
2311 | | * @param offset the offset in the tvb |
2312 | | * @return modified offset |
2313 | | */ |
2314 | | static unsigned |
2315 | | fCharacterString(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label); |
2316 | | |
2317 | | /** |
2318 | | * adds string value to tree |
2319 | | * @param tvb the tv buffer of the current data |
2320 | | * @param pinfo the packet info of the current data |
2321 | | * @param tree the tree to append this item to |
2322 | | * @param offset the offset in the tvb |
2323 | | * @param present_val_dissect exposes string as present_value property |
2324 | | * @param object_name_dissect exposes string as object_name property |
2325 | | * @return modified offset |
2326 | | */ |
2327 | | static unsigned |
2328 | | fCharacterStringBase(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label, |
2329 | | bool present_val_dissect, bool object_name_dissect); |
2330 | | |
2331 | | /** |
2332 | | * adds timeSpan with max 32Bit unsigned Integer Value to tree |
2333 | | * @param tvb the tv buffer of the current data |
2334 | | * @param pinfo the packet info of the current data |
2335 | | * @param tree the tree to append this item to |
2336 | | * @param offset the offset in the tvb |
2337 | | * @return modified offset |
2338 | | */ |
2339 | | static unsigned |
2340 | | fTimeSpan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label); |
2341 | | |
2342 | | /** |
2343 | | * BACnet Application PDUs chapter 21 |
2344 | | * BACnetPropertyIdentifier::= ENUMERATED { |
2345 | | * @see bacapp_property_identifier |
2346 | | * } |
2347 | | * @param tvb the tv buffer of the current data |
2348 | | * @param pinfo the packet info of the current data |
2349 | | * @param tree the tree to append this item to |
2350 | | * @param offset the offset in the tvb |
2351 | | * @return modified offset |
2352 | | */ |
2353 | | static unsigned |
2354 | | fPropertyIdentifier(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2355 | | |
2356 | | /** |
2357 | | * BACnet Application PDUs chapter 21 |
2358 | | * BACnetPropertyArrayIndex::= ENUMERATED { |
2359 | | * @see bacapp_property_array_index |
2360 | | * } |
2361 | | * @param tvb the tv buffer of the current data |
2362 | | * @param pinfo the packet info of the current data |
2363 | | * @param tree the tree to append this item to |
2364 | | * @param offset the offset in the tvb |
2365 | | * @return modified offset |
2366 | | */ |
2367 | | static unsigned |
2368 | | fPropertyArrayIndex(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2369 | | |
2370 | | /** |
2371 | | * listOfEventSummaries ::= SEQUENCE OF SEQUENCE { |
2372 | | * objectIdentifier [0] BACnetObjectIdentifier, |
2373 | | * eventState [1] BACnetEventState, |
2374 | | * acknowledgedTransitions [2] BACnetEventTransitionBits, |
2375 | | * eventTimeStamps [3] SEQUENCE SIZE (3) OF BACnetTimeStamps, |
2376 | | * notifyType [4] BACnetNotifyType, |
2377 | | * eventEnable [5] BACnetEventTransitionBits, |
2378 | | * eventPriorities [6] SEQUENCE SIZE (3) OF Unsigned |
2379 | | * } |
2380 | | * @param tvb the tv buffer of the current data |
2381 | | * @param pinfo the packet info of the current data |
2382 | | * @param tree the tree to append this item to |
2383 | | * @param offset the offset in the tvb |
2384 | | * @return modified offset |
2385 | | */ |
2386 | | static unsigned |
2387 | | flistOfEventSummaries(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2388 | | |
2389 | | /** |
2390 | | * SelectionCriteria ::= SEQUENCE { |
2391 | | * propertyIdentifier [0] BACnetPropertyIdentifier, |
2392 | | * propertyArrayIndex [1] Unsigned OPTIONAL, -- used only with array datatype |
2393 | | * relationSpecifier [2] ENUMERATED { bacapp_relationSpecifier }, |
2394 | | * comparisonValue [3] ABSTRACT-SYNTAX.&Type |
2395 | | * } |
2396 | | * @param tvb the tv buffer of the current data |
2397 | | * @param pinfo the packet info of the current data |
2398 | | * @param tree the tree to append this item to |
2399 | | * @param offset the offset in the tvb |
2400 | | * @return modified offset |
2401 | | */ |
2402 | | static unsigned |
2403 | | fSelectionCriteria(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2404 | | |
2405 | | /** |
2406 | | * objectSelectionCriteria ::= SEQUENCE { |
2407 | | * selectionLogic [0] ENUMERATED { bacapp_selectionLogic }, |
2408 | | * listOfSelectionCriteria [1] SelectionCriteria |
2409 | | * } |
2410 | | * @param tvb the tv buffer of the current data |
2411 | | * @param pinfo the packet info of the current data |
2412 | | * @param subtree the sub tree to append this item to |
2413 | | * @param offset the offset in the tvb |
2414 | | * @return modified offset |
2415 | | */ |
2416 | | static unsigned |
2417 | | fObjectSelectionCriteria(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, unsigned offset); |
2418 | | |
2419 | | /** |
2420 | | * BACnet-Error ::= SEQUENCE { |
2421 | | * error-class ENUMERATED {}, |
2422 | | * error-code ENUMERATED {} |
2423 | | * } |
2424 | | * } |
2425 | | * @param tvb the tv buffer of the current data |
2426 | | * @param pinfo the packet info of the current data |
2427 | | * @param tree the tree to append this item to |
2428 | | * @param offset the offset in the tvb |
2429 | | * @return modified offset |
2430 | | */ |
2431 | | static unsigned |
2432 | | fError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2433 | | |
2434 | | /** |
2435 | | * Adds error-code from BACnet-Error to the tree |
2436 | | * @param tvb the tv buffer of the current data |
2437 | | * @param pinfo the packet info of the current data |
2438 | | * @param tree the tree to append this item to |
2439 | | * @param offset the offset in the tvb |
2440 | | * @return modified offset |
2441 | | */ |
2442 | | static unsigned |
2443 | | fErrorCode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2444 | | |
2445 | | /** |
2446 | | * Adds error-class from BACnet-Error to the tree |
2447 | | * @param tvb the tv buffer of the current data |
2448 | | * @param pinfo the packet info of the current data |
2449 | | * @param tree the tree to append this item to |
2450 | | * @param offset the offset in the tvb |
2451 | | * @return modified offset |
2452 | | */ |
2453 | | static unsigned |
2454 | | fErrorClass(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2455 | | |
2456 | | /** |
2457 | | * Generic handler for context tagged values. Mostly for handling |
2458 | | * vendor-defined properties and services. |
2459 | | * @param tvb the tv buffer of the current data |
2460 | | * @param pinfo the packet info of the current data |
2461 | | * @param tree the tree to append this item to |
2462 | | * @param offset the offset in the tvb |
2463 | | * @return modified offset |
2464 | | * @todo beautify this ugly construct |
2465 | | */ |
2466 | | static unsigned |
2467 | | fContextTaggedValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label); |
2468 | | |
2469 | | /** |
2470 | | * realizes some ABSTRACT-SYNTAX.&Type |
2471 | | * @param tvb the tv buffer of the current data |
2472 | | * @param pinfo the packet info of the current data |
2473 | | * @param tree the tree to append this item to |
2474 | | * @param offset the offset in the tvb |
2475 | | * @return modified offset |
2476 | | * @todo beautify this ugly construct |
2477 | | */ |
2478 | | static unsigned |
2479 | | fAbstractSyntaxNType(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2480 | | |
2481 | | |
2482 | | static unsigned |
2483 | | fBitStringTagVS(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label, |
2484 | | const value_string *src); |
2485 | | |
2486 | | static unsigned |
2487 | | fBitStringTagVSBase(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label, |
2488 | | const value_string *src, bool present_val_dissect); |
2489 | | |
2490 | | static unsigned |
2491 | | fFaultParameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2492 | | |
2493 | | static unsigned |
2494 | | fEventNotificationSubscription(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2495 | | |
2496 | | static unsigned |
2497 | | fLightingCommand(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *lable); |
2498 | | |
2499 | | static unsigned |
2500 | | fColorCommand(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, unsigned offset, const char* lable); |
2501 | | |
2502 | | static unsigned |
2503 | | fXyColor(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, unsigned offset, const char* lable); |
2504 | | |
2505 | | static unsigned |
2506 | | fTimerStateChangeValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2507 | | |
2508 | | static unsigned |
2509 | | fHostNPort(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *lable); |
2510 | | |
2511 | | static unsigned |
2512 | | fBDTEntry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *lable); |
2513 | | |
2514 | | static unsigned |
2515 | | fFDTEntry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *lable); |
2516 | | |
2517 | | static unsigned |
2518 | | fRouterEntry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2519 | | |
2520 | | static unsigned |
2521 | | fVMACEntry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2522 | | |
2523 | | static unsigned |
2524 | | fValueSource(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2525 | | |
2526 | | static unsigned |
2527 | | fAssignedLandingCalls(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2528 | | |
2529 | | static unsigned |
2530 | | fLandingCallStatus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2531 | | |
2532 | | static unsigned |
2533 | | fLandingDoorStatus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2534 | | |
2535 | | static unsigned |
2536 | | fCOVMultipleSubscription(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2537 | | |
2538 | | static unsigned |
2539 | | fNameValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2540 | | |
2541 | | static unsigned |
2542 | | fNameValueCollection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2543 | | |
2544 | | static unsigned |
2545 | | fAuthenticationFactor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2546 | | |
2547 | | static unsigned |
2548 | | fAuthenticationFactorFormat(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2549 | | |
2550 | | static unsigned |
2551 | | fAuthenticationPolicy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2552 | | |
2553 | | static unsigned |
2554 | | fAccessRule(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2555 | | |
2556 | | static unsigned |
2557 | | fChannelValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label); |
2558 | | |
2559 | | static unsigned |
2560 | | fPropertyAccessResult(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2561 | | |
2562 | | static unsigned |
2563 | | fNetworkSecurityPolicy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2564 | | |
2565 | | static unsigned |
2566 | | fSecurityKeySet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2567 | | |
2568 | | static unsigned |
2569 | | fAuditLogRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2570 | | |
2571 | | static unsigned |
2572 | | fStageLimitValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2573 | | |
2574 | | static unsigned |
2575 | | fObjectSelector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset); |
2576 | | |
2577 | | static unsigned |
2578 | | fDeviceAddressProxyTableEntry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label); |
2579 | | |
2580 | | static unsigned |
2581 | | fAccessToken(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label); |
2582 | | |
2583 | | static unsigned |
2584 | | fAuthorizationConstraint(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label); |
2585 | | |
2586 | | static unsigned |
2587 | | fAuthorizationScope(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label); |
2588 | | |
2589 | | static unsigned |
2590 | | fAuthenticationClient(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label); |
2591 | | |
2592 | | static unsigned |
2593 | | fAuthorizationEvent(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label); |
2594 | | |
2595 | | static unsigned |
2596 | | fAuthenticationPeer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label); |
2597 | | |
2598 | | static unsigned |
2599 | | fAuthenticationEvent(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label); |
2600 | | |
2601 | | static unsigned |
2602 | | fAuthorizationPolicy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label); |
2603 | | |
2604 | | static unsigned |
2605 | | fAuthorizationScopeDescription(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label); |
2606 | | |
2607 | | static unsigned |
2608 | | fAuthorizationServer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label); |
2609 | | |
2610 | | static unsigned |
2611 | | fAuthorizationStatus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label); |
2612 | | |
2613 | | |
2614 | | /** |
2615 | | * register_bacapp |
2616 | | */ |
2617 | | void |
2618 | | proto_register_bacapp(void); |
2619 | | |
2620 | | /* <<<< formerly bacapp.h */ |
2621 | | |
2622 | | /* reassembly table for segmented messages */ |
2623 | | static reassembly_table msg_reassembly_table; |
2624 | | |
2625 | | /* some necessary forward function prototypes */ |
2626 | | static unsigned |
2627 | | fApplicationTypesEnumerated(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, |
2628 | | const char *label, const value_string *vs); |
2629 | | |
2630 | | static const char *bacapp_unknown_service_str = "unknown service"; /* Usage: no format specifiers */ |
2631 | | static const char ASHRAE_Reserved_Fmt[] = "(%d) Reserved for Use by ASHRAE"; |
2632 | | static const char Vendor_Proprietary_Fmt[] = "(%d) Vendor Proprietary Value"; |
2633 | | |
2634 | | static const value_string |
2635 | | BACnetTypeName[] = { |
2636 | | { 0, "Confirmed-REQ"}, |
2637 | | { 1, "Unconfirmed-REQ"}, |
2638 | | { 2, "Simple-ACK"}, |
2639 | | { 3, "Complex-ACK"}, |
2640 | | { 4, "Segment-ACK"}, |
2641 | | { 5, "Error"}, |
2642 | | { 6, "Reject"}, |
2643 | | { 7, "Abort"}, |
2644 | | { 0, NULL } |
2645 | | }; |
2646 | | |
2647 | | static const true_false_string segments_follow = { |
2648 | | "Segmented Request", |
2649 | | "Unsegmented Request" |
2650 | | }; |
2651 | | |
2652 | | static const true_false_string more_follow = { |
2653 | | "More Segments Follow", |
2654 | | "No More Segments Follow" |
2655 | | }; |
2656 | | |
2657 | | static const true_false_string segmented_accept = { |
2658 | | "Segmented Response accepted", |
2659 | | "Segmented Response not accepted" |
2660 | | }; |
2661 | | |
2662 | | static const true_false_string |
2663 | | BACnetTagClass = { |
2664 | | "Context Specific Tag", |
2665 | | "Application Tag" |
2666 | | }; |
2667 | | |
2668 | | static const value_string |
2669 | | BACnetMaxSegmentsAccepted [] = { |
2670 | | { 0, "Unspecified"}, |
2671 | | { 1, "2 segments"}, |
2672 | | { 2, "4 segments"}, |
2673 | | { 3, "8 segments"}, |
2674 | | { 4, "16 segments"}, |
2675 | | { 5, "32 segments"}, |
2676 | | { 6, "64 segments"}, |
2677 | | { 7, "Greater than 64 segments"}, |
2678 | | { 0, NULL } |
2679 | | }; |
2680 | | |
2681 | | static const value_string |
2682 | | BACnetMaxAPDULengthAccepted [] = { |
2683 | | { 0, "Up to MinimumMessageSize (50 octets)"}, |
2684 | | { 1, "Up to 128 octets"}, |
2685 | | { 2, "Up to 206 octets (fits in a LonTalk frame)"}, |
2686 | | { 3, "Up to 480 octets (fits in an ARCNET frame)"}, |
2687 | | { 4, "Up to 1024 octets"}, |
2688 | | { 5, "Up to 1476 octets (fits in an ISO 8802-3 frame)"}, |
2689 | | { 6, "reserved by ASHRAE"}, |
2690 | | { 7, "reserved by ASHRAE"}, |
2691 | | { 8, "reserved by ASHRAE"}, |
2692 | | { 9, "reserved by ASHRAE"}, |
2693 | | { 10, "reserved by ASHRAE"}, |
2694 | | { 11, "reserved by ASHRAE"}, |
2695 | | { 12, "reserved by ASHRAE"}, |
2696 | | { 13, "reserved by ASHRAE"}, |
2697 | | { 14, "reserved by ASHRAE"}, |
2698 | | { 15, "reserved by ASHRAE"}, |
2699 | | { 0, NULL} |
2700 | | }; |
2701 | | |
2702 | | static const value_string |
2703 | | BACnetRejectReason [] = { |
2704 | | { 0, "other"}, |
2705 | | { 1, "buffer-overflow"}, |
2706 | | { 2, "inconsistent-parameters"}, |
2707 | | { 3, "invalid-parameter-data-type"}, |
2708 | | { 4, "invalid-tag"}, |
2709 | | { 5, "missing-required-parameter"}, |
2710 | | { 6, "parameter-out-of-range"}, |
2711 | | { 7, "too-many-arguments"}, |
2712 | | { 8, "undefined-enumeration"}, |
2713 | | { 9, "unrecognized-service"}, |
2714 | | { 0, NULL} |
2715 | | }; |
2716 | | |
2717 | | static const value_string |
2718 | | BACnetRestartReason [] = { |
2719 | | { 0, "unknown"}, |
2720 | | { 1, "coldstart"}, |
2721 | | { 2, "warmstart"}, |
2722 | | { 3, "detected-power-lost"}, |
2723 | | { 4, "detected-powered-off"}, |
2724 | | { 5, "hardware-watchdog"}, |
2725 | | { 6, "software-watchdog"}, |
2726 | | { 7, "suspended"}, |
2727 | | { 8, "activate-changes"}, |
2728 | | { 0, NULL} |
2729 | | }; |
2730 | | |
2731 | | static const value_string |
2732 | | BACnetApplicationTagNumber [] = { |
2733 | | { 0, "Null"}, |
2734 | | { 1, "Boolean"}, |
2735 | | { 2, "Unsigned Integer"}, |
2736 | | { 3, "Signed Integer (2's complement notation)"}, |
2737 | | { 4, "Real (ANSI/IEE-754 floating point)"}, |
2738 | | { 5, "Double (ANSI/IEE-754 double precision floating point)"}, |
2739 | | { 6, "Octet String"}, |
2740 | | { 7, "Character String"}, |
2741 | | { 8, "Bit String"}, |
2742 | | { 9, "Enumerated"}, |
2743 | | { 10, "Date"}, |
2744 | | { 11, "Time"}, |
2745 | | { 12, "BACnetObjectIdentifier"}, |
2746 | | { 13, "reserved by ASHRAE"}, |
2747 | | { 14, "reserved by ASHRAE"}, |
2748 | | { 15, "reserved by ASHRAE"}, |
2749 | | { 0, NULL} |
2750 | | }; |
2751 | | |
2752 | | static const value_string |
2753 | | BACnetAction [] = { |
2754 | | { 0, "direct"}, |
2755 | | { 1, "reverse"}, |
2756 | | { 0, NULL} |
2757 | | }; |
2758 | | |
2759 | | static const value_string |
2760 | | BACnetAccessEvent [] = { |
2761 | | { 0, "none"}, |
2762 | | { 1, "granted"}, |
2763 | | { 2, "muster"}, |
2764 | | { 3, "passback-detected"}, |
2765 | | { 4, "duress"}, |
2766 | | { 5, "trace"}, |
2767 | | { 6, "lockout-max-attempts"}, |
2768 | | { 7, "lockout-other"}, |
2769 | | { 8, "lockout-relinquished"}, |
2770 | | { 9, "lockout-by-higher-priority"}, |
2771 | | { 10, "out-of-service"}, |
2772 | | { 11, "out-of-service-relinquished"}, |
2773 | | { 12, "accompaniment-by"}, |
2774 | | { 13, "authentication-factor-read"}, |
2775 | | { 14, "authorization-delayed"}, |
2776 | | { 15, "verification-required"}, |
2777 | | /* Enumerated values 128-511 are used for events |
2778 | | * which indicate that access has been denied. */ |
2779 | | { 128, "denied-deny-all"}, |
2780 | | { 129, "denied-unknown-credential"}, |
2781 | | { 130, "denied-authentication-unavailable"}, |
2782 | | { 131, "denied-authentication-factor-timeout"}, |
2783 | | { 132, "denied-incorrect-authentication-factor"}, |
2784 | | { 133, "denied-zone-no-access-rights"}, |
2785 | | { 134, "denied-point-no-access-rights"}, |
2786 | | { 135, "denied-no-access-rights"}, |
2787 | | { 136, "denied-out-of-time-range"}, |
2788 | | { 137, "denied-threat-level"}, |
2789 | | { 138, "denied-passback"}, |
2790 | | { 139, "denied-unexpected-location-usage"}, |
2791 | | { 140, "denied-max-attempts"}, |
2792 | | { 141, "denied-lower-occupancy-limit"}, |
2793 | | { 142, "denied-upper-occupancy-limit"}, |
2794 | | { 143, "denied-authentication-factor-lost"}, |
2795 | | { 144, "denied-authentication-factor-stolen"}, |
2796 | | { 145, "denied-authentication-factor-damaged"}, |
2797 | | { 146, "denied-authentication-factor-destroyed"}, |
2798 | | { 147, "denied-authentication-factor-disabled"}, |
2799 | | { 148, "denied-authentication-factor-error"}, |
2800 | | { 149, "denied-credential-unassigned"}, |
2801 | | { 150, "denied-credential-not-provisioned"}, |
2802 | | { 151, "denied-credential-not-yet-active"}, |
2803 | | { 152, "denied-credential-expired"}, |
2804 | | { 153, "denied-credential-manual-disable"}, |
2805 | | { 154, "denied-credential-lockout"}, |
2806 | | { 155, "denied-credential-max-days"}, |
2807 | | { 156, "denied-credential-max-uses"}, |
2808 | | { 157, "denied-credential-inactivity"}, |
2809 | | { 158, "denied-credential-disabled"}, |
2810 | | { 159, "denied-no-accompaniment"}, |
2811 | | { 160, "denied-incorrect-accompaniment"}, |
2812 | | { 161, "denied-lockout"}, |
2813 | | { 162, "denied-verification-failed"}, |
2814 | | { 163, "denied-verification-timeout"}, |
2815 | | { 164, "denied-other"}, |
2816 | | { 0, NULL} |
2817 | | /* Enumerated values 0-512 are reserved for definition by ASHRAE. |
2818 | | Enumerated values 512-65535 may be used by others subject to |
2819 | | procedures and constraints described in Clause 23. */ |
2820 | | }; |
2821 | | |
2822 | | static const value_string |
2823 | | BACnetAccessZoneOccupancyState[] = { |
2824 | | { 0, "normal"}, |
2825 | | { 1, "below-lower-limit"}, |
2826 | | { 2, "at-lower-limit"}, |
2827 | | { 3, "at-upper-limit"}, |
2828 | | { 4, "above-upper-limit"}, |
2829 | | { 5, "disabled"}, |
2830 | | { 6, "not-supported"}, |
2831 | | { 0, NULL} |
2832 | | }; |
2833 | | |
2834 | | static const value_string |
2835 | | BACnetAccessPassbackMode[] = { |
2836 | | { 0, "passback-off" }, |
2837 | | { 1, "hard-passback" }, |
2838 | | { 2, "soft-passback" }, |
2839 | | { 0, NULL } |
2840 | | }; |
2841 | | |
2842 | | static const value_string |
2843 | | BACnetAccessCredentialDisableReason[] = { |
2844 | | { 0, "disabled" }, |
2845 | | { 1, "disabled-needs-provisioning" }, |
2846 | | { 2, "disabled-unassigned" }, |
2847 | | { 3, "disabled-not-yet-active" }, |
2848 | | { 4, "disabled-expired" }, |
2849 | | { 5, "disabled-lockout" }, |
2850 | | { 6, "disabled-max-days" }, |
2851 | | { 7, "disabled-max-uses" }, |
2852 | | { 8, "disabled-inactivity" }, |
2853 | | { 9, "disabled-manual" }, |
2854 | | { 0, NULL } |
2855 | | }; |
2856 | | |
2857 | | static const value_string |
2858 | | BACnetAccessUserType[] = { |
2859 | | { 0, "asset" }, |
2860 | | { 1, "group" }, |
2861 | | { 2, "person" }, |
2862 | | { 0, NULL } |
2863 | | }; |
2864 | | |
2865 | | static const value_string |
2866 | | BACnetWriteStatus[] = { |
2867 | | { 0, "idle" }, |
2868 | | { 1, "in-progress" }, |
2869 | | { 2, "successful" }, |
2870 | | { 3, "failed" }, |
2871 | | { 0, NULL } |
2872 | | }; |
2873 | | |
2874 | | static const value_string |
2875 | | BACnetLightingTransition[] = { |
2876 | | { 0, "none" }, |
2877 | | { 1, "fade" }, |
2878 | | { 2, "ramp" }, |
2879 | | { 0, NULL } |
2880 | | }; |
2881 | | |
2882 | | static const value_string |
2883 | | BACnetSecurityLevel[] = { |
2884 | | { 0, "incapable" }, |
2885 | | { 1, "plain" }, |
2886 | | { 2, "signed" }, |
2887 | | { 3, "encrypted" }, |
2888 | | { 4, "signed-end-to-end" }, |
2889 | | { 5, "encrypted-end-to-end" }, |
2890 | | { 0, NULL } |
2891 | | }; |
2892 | | |
2893 | | static const value_string |
2894 | | BACnetAccessCredentialDisable[] = { |
2895 | | { 0, "none" }, |
2896 | | { 1, "disable" }, |
2897 | | { 2, "disable-manual" }, |
2898 | | { 3, "disable-lockout" }, |
2899 | | { 0, NULL } |
2900 | | }; |
2901 | | |
2902 | | static const value_string |
2903 | | BACnetAuthenticationStatus[] = { |
2904 | | { 0, "not-ready" }, |
2905 | | { 1, "ready" }, |
2906 | | { 2, "disabled" }, |
2907 | | { 3, "waiting-for-authentication-factor" }, |
2908 | | { 4, "waiting-for-accompaniment" }, |
2909 | | { 5, "waiting-for-verification" }, |
2910 | | { 6, "in-progress" }, |
2911 | | { 0, NULL } |
2912 | | }; |
2913 | | |
2914 | | static const value_string |
2915 | | BACnetAuthorizationMode[] = { |
2916 | | { 0, "authorize" }, |
2917 | | { 1, "grant-active" }, |
2918 | | { 2, "deny-all" }, |
2919 | | { 3, "verification-required" }, |
2920 | | { 4, "authorization-delayed" }, |
2921 | | { 5, "none" }, |
2922 | | { 0, NULL } |
2923 | | }; |
2924 | | |
2925 | | static const value_string |
2926 | | BACnetAuthorizationExemption[] = { |
2927 | | { 0, "passback" }, |
2928 | | { 1, "occupancy-check" }, |
2929 | | { 2, "access-rights" }, |
2930 | | { 3, "lockout" }, |
2931 | | { 4, "deny" }, |
2932 | | { 5, "verification" }, |
2933 | | { 6, "authorization-delay" }, |
2934 | | { 0, NULL } |
2935 | | }; |
2936 | | |
2937 | | static const value_string |
2938 | | BACnetLightingInProgress[] = { |
2939 | | { 0, "idle" }, |
2940 | | { 1, "fade-active" }, |
2941 | | { 2, "ramp-active" }, |
2942 | | { 3, "not-controlled" }, |
2943 | | { 4, "other" }, |
2944 | | { 5, "trim-active" }, |
2945 | | { 0, NULL } |
2946 | | }; |
2947 | | |
2948 | | static const value_string |
2949 | | BACnetColorOperationInProgress[] = { |
2950 | | { 0, "idle" }, |
2951 | | { 1, "fade-active" }, |
2952 | | { 2, "ramp-active" }, |
2953 | | { 3, "not-controlled" }, |
2954 | | { 4, "other" }, |
2955 | | { 0, NULL } |
2956 | | }; |
2957 | | |
2958 | | static const value_string |
2959 | | BACnetColorTransition[] = { |
2960 | | { 0, "none" }, |
2961 | | { 1, "fade" }, |
2962 | | { 2, "ramp" }, |
2963 | | { 0, NULL } |
2964 | | }; |
2965 | | |
2966 | | static const value_string |
2967 | | BACnetBinaryLightingPV[] = { |
2968 | | { 0, "off" }, |
2969 | | { 1, "on" }, |
2970 | | { 2, "warn" }, |
2971 | | { 3, "warn-off" }, |
2972 | | { 4, "warn-relinquish" }, |
2973 | | { 5, "stop" }, |
2974 | | { 6, "toggle" }, |
2975 | | { 0, NULL } |
2976 | | }; |
2977 | | |
2978 | | static const value_string |
2979 | | BACnetBackupState[] = { |
2980 | | { 0, "idle"}, |
2981 | | { 1, "preparing-for-backup"}, |
2982 | | { 2, "preparing-for-restore"}, |
2983 | | { 3, "performing-a-backup"}, |
2984 | | { 4, "performing-a-restore"}, |
2985 | | { 5, "backup-failure"}, |
2986 | | { 6, "restore-failure"}, |
2987 | | { 0, NULL} |
2988 | | }; |
2989 | | |
2990 | | static const value_string |
2991 | | BACnetAcknowledgedTransitions[] = { |
2992 | | { 0, "to-offnormal" }, |
2993 | | { 1, "to-fault" }, |
2994 | | { 2, "to-normal" }, |
2995 | | { 0, NULL } |
2996 | | }; |
2997 | | |
2998 | | static const value_string |
2999 | | BACnetFileAccessMethod [] = { |
3000 | | { 0, "record-access"}, |
3001 | | { 1, "stream-access"}, |
3002 | | { 0, NULL} |
3003 | | }; |
3004 | | |
3005 | | /* For some reason, BACnet defines the choice parameter |
3006 | | in the file read and write services backwards from the |
3007 | | BACnetFileAccessMethod enumeration. |
3008 | | */ |
3009 | | static const value_string |
3010 | | BACnetFileAccessOption [] = { |
3011 | | { 0, "stream access"}, |
3012 | | { 1, "record access"}, |
3013 | | { 0, NULL} |
3014 | | }; |
3015 | | |
3016 | | static const value_string |
3017 | | BACnetFileStartOption [] = { |
3018 | | { 0, "File Start Position: "}, |
3019 | | { 1, "File Start Record: "}, |
3020 | | { 0, NULL} |
3021 | | }; |
3022 | | |
3023 | | static const value_string |
3024 | | BacnetFileRequestedCount [] = { |
3025 | | { 0, "Requested Octet Count: "}, |
3026 | | { 1, "Requested Record Count: "}, |
3027 | | { 0, NULL} |
3028 | | }; |
3029 | | |
3030 | | static const value_string |
3031 | | BACnetFileWriteInfo [] = { |
3032 | | { 0, "File Data: "}, |
3033 | | { 1, "Record Count: "}, |
3034 | | { 0, NULL} |
3035 | | }; |
3036 | | |
3037 | | static const value_string |
3038 | | BACnetAbortReason [] = { |
3039 | | { 0, "other"}, |
3040 | | { 1, "buffer-overflow"}, |
3041 | | { 2, "invalid-apdu-in-this-state"}, |
3042 | | { 3, "preempted-by-higher-priority-task"}, |
3043 | | { 4, "segmentation-not-supported"}, |
3044 | | { 5, "security-error"}, |
3045 | | { 6, "insufficient-security"}, |
3046 | | { 7, "window-size-out-of-range"}, |
3047 | | { 8, "application-exceeded-reply-time"}, |
3048 | | { 9, "out-of-resources"}, |
3049 | | { 10, "tsm-timeout"}, |
3050 | | { 11, "apdu-too-long"}, |
3051 | | { 0, NULL} |
3052 | | }; |
3053 | | |
3054 | | static const value_string |
3055 | | BACnetIpMode [] = { |
3056 | | { 0, "normal"}, |
3057 | | { 1, "foreign"}, |
3058 | | { 2, "bbmd"}, |
3059 | | { 0, NULL} |
3060 | | }; |
3061 | | |
3062 | | static const value_string |
3063 | | BACnetNetworkPortCommand [] = { |
3064 | | { 0, "idle"}, |
3065 | | { 1, "discard-changes"}, |
3066 | | { 2, "renew-fd-registration"}, |
3067 | | { 3, "restart-slave-discovery"}, |
3068 | | { 4, "renew-dhcp"}, |
3069 | | { 5, "restart-autonegotiation"}, |
3070 | | { 6, "disconnect"}, |
3071 | | { 7, "restart-port"}, |
3072 | | { 8, "generate-csr-file"}, |
3073 | | { 9, "validate-changes"}, |
3074 | | { 10, "restart-device-discovery"}, |
3075 | | { 0, NULL} |
3076 | | }; |
3077 | | |
3078 | | static const value_string |
3079 | | BACnetNetworkNumberQuality [] = { |
3080 | | { 0, "unknown"}, |
3081 | | { 1, "learned"}, |
3082 | | { 2, "learned-configured"}, |
3083 | | { 3, "configured"}, |
3084 | | { 0, NULL} |
3085 | | }; |
3086 | | |
3087 | | static const value_string |
3088 | | BACnetNetworkType [] = { |
3089 | | { 0, "ethernet" }, |
3090 | | { 1, "arcnet" }, |
3091 | | { 2, "mstp" }, |
3092 | | { 3, "ptp" }, |
3093 | | { 4, "lontalk" }, |
3094 | | { 5, "bacnet-ipv4" }, |
3095 | | { 6, "zigbee" }, |
3096 | | { 7, "virtual" }, |
3097 | | { 8, "non-bacnet" }, |
3098 | | { 9, "bacnet-ipv6" }, |
3099 | | {10, "serial" }, |
3100 | | {11, "secure-connect" }, |
3101 | | { 0, NULL} |
3102 | | }; |
3103 | | |
3104 | | static const value_string |
3105 | | BACnetSCConnectionState [] = { |
3106 | | { 0, "not-connected" }, |
3107 | | { 1, "connected" }, |
3108 | | { 2, "disconnected-with-errors" }, |
3109 | | { 3, "failed-to-connect" }, |
3110 | | { 0, NULL} |
3111 | | }; |
3112 | | |
3113 | | static const value_string |
3114 | | BACnetSCHubConnectorState [] = { |
3115 | | { 0, "no-hub-connection" }, |
3116 | | { 1, "connected-to-primary" }, |
3117 | | { 2, "connected-to-failover" }, |
3118 | | { 0, NULL} |
3119 | | }; |
3120 | | |
3121 | | static const value_string |
3122 | | BACnetLifeSafetyMode [] = { |
3123 | | { 0, "off"}, |
3124 | | { 1, "on"}, |
3125 | | { 2, "test"}, |
3126 | | { 3, "manned"}, |
3127 | | { 4, "unmanned"}, |
3128 | | { 5, "armed"}, |
3129 | | { 6, "disarmed"}, |
3130 | | { 7, "prearmed"}, |
3131 | | { 8, "slow"}, |
3132 | | { 9, "fast"}, |
3133 | | { 10, "disconnected"}, |
3134 | | { 11, "enabled"}, |
3135 | | { 12, "disabled"}, |
3136 | | { 13, "atomic-release-disabled"}, |
3137 | | { 14, "default"}, |
3138 | | { 15, "activated-oeo-alarm"}, |
3139 | | { 16, "activated-oeo-evacuate"}, |
3140 | | { 17, "activated-oeo-phase1-recall"}, |
3141 | | { 18, "activated-oeo-unavailable"}, |
3142 | | { 19, "deactivated"}, |
3143 | | { 0, NULL} |
3144 | | /* Enumerated values 0-255 are reserved for definition by ASHRAE. |
3145 | | Enumerated values 256-65535 may be used by others subject to |
3146 | | procedures and constraints described in Clause 23. */ |
3147 | | }; |
3148 | | |
3149 | | static const value_string |
3150 | | BACnetLifeSafetyOperation [] = { |
3151 | | { 0, "none"}, |
3152 | | { 1, "silence"}, |
3153 | | { 2, "silence-audible"}, |
3154 | | { 3, "silence-visual"}, |
3155 | | { 4, "reset"}, |
3156 | | { 5, "reset-alarm"}, |
3157 | | { 6, "reset-fault"}, |
3158 | | { 7, "unsilence"}, |
3159 | | { 8, "unsilence-audible"}, |
3160 | | { 9, "unsilence-visual"}, |
3161 | | { 0, NULL} |
3162 | | /* Enumerated values 0-63 are reserved for definition by ASHRAE. |
3163 | | Enumerated values 64-65535 may be used by others subject to |
3164 | | procedures and constraints described in Clause 23. */ |
3165 | | }; |
3166 | | |
3167 | | static const value_string |
3168 | | BACnetLifeSafetyState [] = { |
3169 | | { 0, "quiet"}, |
3170 | | { 1, "pre-alarm"}, |
3171 | | { 2, "alarm"}, |
3172 | | { 3, "fault"}, |
3173 | | { 4, "fault-pre-alarm"}, |
3174 | | { 5, "fault-alarm"}, |
3175 | | { 6, "not-ready"}, |
3176 | | { 7, "active"}, |
3177 | | { 8, "tamper"}, |
3178 | | { 9, "test-alarm"}, |
3179 | | { 10, "test-active"}, |
3180 | | { 11, "test-fault"}, |
3181 | | { 12, "test-fault-alarm"}, |
3182 | | { 13, "holdup"}, |
3183 | | { 14, "duress"}, |
3184 | | { 15, "tamper-alarm"}, |
3185 | | { 16, "abnormal"}, |
3186 | | { 17, "emergency-power"}, |
3187 | | { 18, "delayed"}, |
3188 | | { 19, "blocked"}, |
3189 | | { 20, "local-alarm"}, |
3190 | | { 21, "general-alarm"}, |
3191 | | { 22, "supervisory"}, |
3192 | | { 23, "test-supervisory"}, |
3193 | | { 24, "non-default-mode"}, |
3194 | | { 25, "oeo-unavailable"}, |
3195 | | { 26, "oeo-alarm"}, |
3196 | | { 27, "oeo-phase1-recall"}, |
3197 | | { 28, "oeo-evacuate"}, |
3198 | | { 29, "oeo-unaffected"}, |
3199 | | { 30, "test-oeo-unavailable"}, |
3200 | | { 31, "test-oeo-alarm"}, |
3201 | | { 32, "test-oeo-phase1-recall"}, |
3202 | | { 33, "test-oeo-evacuate"}, |
3203 | | { 34, "test-oeo-unaffected"}, |
3204 | | { 0, NULL} |
3205 | | /* Enumerated values 0-255 are reserved for definition by ASHRAE. |
3206 | | Enumerated values 256-65535 may be used by others subject to |
3207 | | procedures and constraints described in Clause 23. */ |
3208 | | }; |
3209 | | |
3210 | | static const value_string |
3211 | | BACnetLimitEnable[] = { |
3212 | | { 0, "low-limit-enable" }, |
3213 | | { 1, "high-limit-enable" }, |
3214 | | { 0, NULL } |
3215 | | }; |
3216 | | |
3217 | | static const value_string |
3218 | | BACnetTimerState [] = { |
3219 | | { 0, "idle"}, |
3220 | | { 1, "running"}, |
3221 | | { 2, "expired"}, |
3222 | | { 0, NULL} |
3223 | | }; |
3224 | | |
3225 | | static const value_string |
3226 | | BACnetTimerTransition [] = { |
3227 | | { 0, "none"}, |
3228 | | { 1, "idle-to-running"}, |
3229 | | { 2, "running-to-idle"}, |
3230 | | { 3, "running-to-running"}, |
3231 | | { 4, "running-to-expired"}, |
3232 | | { 5, "forced-to-expired"}, |
3233 | | { 6, "expired-to-idle"}, |
3234 | | { 7, "expired-to-running"}, |
3235 | | { 0, NULL} |
3236 | | }; |
3237 | | |
3238 | | static const value_string |
3239 | | BACnetEscalatorFault [] = { |
3240 | | { 0, "controller-fault"}, |
3241 | | { 1, "drive-and-motor-fault"}, |
3242 | | { 2, "mechanical-component-fault"}, |
3243 | | { 3, "overspeed-fault"}, |
3244 | | { 4, "power-supply-fault"}, |
3245 | | { 5, "safety-device-fault"}, |
3246 | | { 6, "controller-supply-fault"}, |
3247 | | { 7, "drive-temperature-exceeded"}, |
3248 | | { 8, "comb-plate-fault"}, |
3249 | | { 0, NULL} |
3250 | | }; |
3251 | | |
3252 | | static const value_string |
3253 | | BACnetEscalatorMode [] = { |
3254 | | { 0, "unknown"}, |
3255 | | { 1, "stop"}, |
3256 | | { 2, "up"}, |
3257 | | { 3, "down"}, |
3258 | | { 4, "inspection"}, |
3259 | | { 5, "out-of-service"}, |
3260 | | { 0, NULL} |
3261 | | }; |
3262 | | |
3263 | | static const value_string |
3264 | | BACnetEscalatorOperationDirection [] = { |
3265 | | { 0, "unknown"}, |
3266 | | { 1, "stopped"}, |
3267 | | { 2, "up-rated-speed"}, |
3268 | | { 3, "up-reduced-speed"}, |
3269 | | { 4, "down-rated-speed"}, |
3270 | | { 5, "down-reduced-speed"}, |
3271 | | { 0, NULL} |
3272 | | }; |
3273 | | |
3274 | | static const value_string |
3275 | | BACnetLiftCarDirection [] = { |
3276 | | { 0, "unknown"}, |
3277 | | { 1, "none"}, |
3278 | | { 2, "stopped"}, |
3279 | | { 3, "up"}, |
3280 | | { 4, "down"}, |
3281 | | { 5, "up-and-down"}, |
3282 | | { 0, NULL} |
3283 | | }; |
3284 | | |
3285 | | static const value_string |
3286 | | BACnetLiftCarDoorCommand [] = { |
3287 | | { 0, "none"}, |
3288 | | { 1, "open"}, |
3289 | | { 2, "close"}, |
3290 | | { 0, NULL} |
3291 | | }; |
3292 | | |
3293 | | static const value_string |
3294 | | BACnetLiftCarDriveStatus [] = { |
3295 | | { 0, "unknown"}, |
3296 | | { 1, "stationary"}, |
3297 | | { 2, "braking"}, |
3298 | | { 3, "accelerate"}, |
3299 | | { 4, "decelerate"}, |
3300 | | { 5, "rated-speed"}, |
3301 | | { 6, "single-floor-jump"}, |
3302 | | { 7, "two-floor-jump"}, |
3303 | | { 8, "three-floor-jump"}, |
3304 | | { 9, "multi-floor-jump"}, |
3305 | | { 0, NULL} |
3306 | | }; |
3307 | | |
3308 | | static const value_string |
3309 | | BACnetLiftCarMode [] = { |
3310 | | { 0, "unknown"}, |
3311 | | { 1, "normal"}, |
3312 | | { 2, "vip"}, |
3313 | | { 3, "homing"}, |
3314 | | { 4, "parking"}, |
3315 | | { 5, "attendant-control"}, |
3316 | | { 6, "firefighter-control"}, |
3317 | | { 7, "emergency-power"}, |
3318 | | { 8, "inspection"}, |
3319 | | { 9, "cabinet-recall"}, |
3320 | | { 10, "earthquake-operation"}, |
3321 | | { 11, "fire-operation"}, |
3322 | | { 12, "out-of-service"}, |
3323 | | { 13, "occupant-evacuation"}, |
3324 | | { 0, NULL} |
3325 | | }; |
3326 | | |
3327 | | static const value_string |
3328 | | BACnetLiftFault [] = { |
3329 | | { 0, "controller-fault"}, |
3330 | | { 1, "drive-and-motor-fault"}, |
3331 | | { 2, "governor-and-safety-gear-fault"}, |
3332 | | { 3, "lift-shaft-device-fault"}, |
3333 | | { 4, "power-supply-fault"}, |
3334 | | { 5, "safety-interlock-fault"}, |
3335 | | { 6, "door-closing-fault"}, |
3336 | | { 7, "door-opening-fault"}, |
3337 | | { 8, "car-stopped-outside-landing-zone"}, |
3338 | | { 9, "call-button-stuck"}, |
3339 | | { 10, "start-failure"}, |
3340 | | { 11, "controller-supply-fault"}, |
3341 | | { 12, "self-test-failure"}, |
3342 | | { 13, "runtime-limit-exceeded"}, |
3343 | | { 14, "position-lost"}, |
3344 | | { 15, "drive-temperature-exceeded"}, |
3345 | | { 16, "load-measurement-fault"}, |
3346 | | { 0, NULL} |
3347 | | }; |
3348 | | |
3349 | | static const value_string |
3350 | | BACnetLiftGroupMode [] = { |
3351 | | { 0, "unknown"}, |
3352 | | { 1, "normal"}, |
3353 | | { 2, "down-peak"}, |
3354 | | { 3, "two-way"}, |
3355 | | { 4, "four-way"}, |
3356 | | { 5, "emergency-power"}, |
3357 | | { 6, "up-peak"}, |
3358 | | { 0, NULL} |
3359 | | }; |
3360 | | |
3361 | | static const value_string |
3362 | | BACnetProtocolLevel [] = { |
3363 | | { 0, "physical"}, |
3364 | | { 1, "protocol"}, |
3365 | | { 2, "bacnet-application"}, |
3366 | | { 3, "non-bacnet-application"}, |
3367 | | { 0, NULL} |
3368 | | }; |
3369 | | |
3370 | | static const value_string |
3371 | | BACnetRelationship [] = { |
3372 | | { 0, "unknown"}, |
3373 | | { 1, "default"}, |
3374 | | { 2, "contains"}, |
3375 | | { 3, "contained-by"}, |
3376 | | { 4, "uses"}, |
3377 | | { 5, "used-by"}, |
3378 | | { 6, "commands"}, |
3379 | | { 7, "commanded-by"}, |
3380 | | { 8, "adjusts"}, |
3381 | | { 9, "adjusted-by"}, |
3382 | | { 10, "ingress"}, |
3383 | | { 11, "egress"}, |
3384 | | { 12, "supplies-air"}, |
3385 | | { 13, "receives-air"}, |
3386 | | { 14, "supplies-hot-air"}, |
3387 | | { 15, "receives-hot-air"}, |
3388 | | { 16, "supplies-cool-air"}, |
3389 | | { 17, "receives-cool-air"}, |
3390 | | { 18, "supplies-power"}, |
3391 | | { 19, "receives-power"}, |
3392 | | { 20, "supplies-gas"}, |
3393 | | { 21, "receives-gas"}, |
3394 | | { 22, "supplies-water"}, |
3395 | | { 23, "receives-water"}, |
3396 | | { 24, "supplies-hot-water"}, |
3397 | | { 25, "receives-hot-water"}, |
3398 | | { 26, "supplies-cool-water"}, |
3399 | | { 27, "receives-cool-water"}, |
3400 | | { 28, "supplies-steam"}, |
3401 | | { 29, "receives-steam"}, |
3402 | | { 0, NULL} |
3403 | | }; |
3404 | | |
3405 | | static const value_string |
3406 | | BACnetLightingOperation[] = { |
3407 | | { 0, "none" }, |
3408 | | { 1, "fade-to" }, |
3409 | | { 2, "ramp-to" }, |
3410 | | { 3, "step-up" }, |
3411 | | { 4, "step-down" }, |
3412 | | { 5, "step-on" }, |
3413 | | { 6, "step-off" }, |
3414 | | { 7, "warn" }, |
3415 | | { 8, "warn-off" }, |
3416 | | { 9, "warn-relinquish" }, |
3417 | | { 10, "stop" }, |
3418 | | { 11, "restore-on" }, |
3419 | | { 12, "default-on" }, |
3420 | | { 13, "toggle-restor" }, |
3421 | | { 14, "toggle-default" }, |
3422 | | { 0, NULL } |
3423 | | }; |
3424 | | |
3425 | | static const value_string |
3426 | | BACnetColorOperation[] = { |
3427 | | { 0, "none" }, |
3428 | | { 1, "fade-to-color" }, |
3429 | | { 2, "fade-to-cct" }, |
3430 | | { 3, "ramp-to-cct" }, |
3431 | | { 4, "step-up-cct" }, |
3432 | | { 5, "step-down-cct" }, |
3433 | | { 6, "stop" }, |
3434 | | { 0, NULL } |
3435 | | }; |
3436 | | |
3437 | | static const value_string |
3438 | | BACnetConfirmedServiceChoice[] = { |
3439 | | { 0, "acknowledgeAlarm"}, |
3440 | | { 1, "confirmedCOVNotification"}, |
3441 | | { 2, "confirmedEventNotification"}, |
3442 | | { 3, "getAlarmSummary"}, |
3443 | | { 4, "getEnrollmentSummary"}, |
3444 | | { 5, "subscribeCOV"}, |
3445 | | { 6, "atomicReadFile"}, |
3446 | | { 7, "atomicWriteFile"}, |
3447 | | { 8, "addListElement"}, |
3448 | | { 9, "removeListElement"}, |
3449 | | { 10, "createObject"}, |
3450 | | { 11, "deleteObject"}, |
3451 | | { 12, "readProperty"}, |
3452 | | { 13, "readPropertyConditional"}, |
3453 | | { 14, "readPropertyMultiple"}, |
3454 | | { 15, "writeProperty"}, |
3455 | | { 16, "writePropertyMultiple"}, |
3456 | | { 17, "deviceCommunicationControl"}, |
3457 | | { 18, "confirmedPrivateTransfer"}, |
3458 | | { 19, "confirmedTextMessage"}, |
3459 | | { 20, "reinitializeDevice"}, |
3460 | | { 21, "vtOpen"}, |
3461 | | { 22, "vtClose"}, |
3462 | | { 23, "vtData"}, |
3463 | | { 24, "authenticate"}, |
3464 | | { 25, "requestKey"}, |
3465 | | { 26, "readRange"}, |
3466 | | { 27, "lifeSafetyOperation"}, |
3467 | | { 28, "subscribeCOVProperty"}, |
3468 | | { 29, "getEventInformation"}, |
3469 | | { 30, "subscribeCovPropertyMultiple"}, |
3470 | | { 31, "confirmedCovNotificationMultiple"}, |
3471 | | { 32, "confirmedAuditNotification"}, |
3472 | | { 33, "auditLogQuery"}, |
3473 | | { 34, "aurthRequest" }, |
3474 | | { 0, NULL} |
3475 | | }; |
3476 | | |
3477 | | static const value_string |
3478 | | BACnetReliability [] = { |
3479 | | { 0, "no-fault-detected"}, |
3480 | | { 1, "no-sensor"}, |
3481 | | { 2, "over-range"}, |
3482 | | { 3, "under-range"}, |
3483 | | { 4, "open-loop"}, |
3484 | | { 5, "shorted-loop"}, |
3485 | | { 6, "no-output"}, |
3486 | | { 7, "unreliable-other"}, |
3487 | | { 8, "process-error"}, |
3488 | | { 9, "multi-state-fault"}, |
3489 | | { 10, "configuration-error"}, |
3490 | | { 11, "reserved for a future addendum"}, |
3491 | | { 12, "communication-failure"}, |
3492 | | { 13, "member-fault"}, |
3493 | | { 14, "monitored-object-fault" }, |
3494 | | { 15, "tripped"}, |
3495 | | { 16, "lamp-failure"}, |
3496 | | { 17, "activation-failure"}, |
3497 | | { 18, "renew-dhcp-failure"}, |
3498 | | { 19, "renew-fd-registration-failure"}, |
3499 | | { 20, "restart-auto-negotiation-failure"}, |
3500 | | { 21, "restart-failure"}, |
3501 | | { 22, "proprietary-command-failure"}, |
3502 | | { 23, "faults-listed"}, |
3503 | | { 24, "referenced-object-fault"}, |
3504 | | { 25, "multi-state-out-of-range"}, |
3505 | | { 0, NULL} |
3506 | | }; |
3507 | | |
3508 | | static const value_string |
3509 | | BACnetRouterStatus[] = { |
3510 | | { 0, "available" }, |
3511 | | { 1, "busy" }, |
3512 | | { 2, "disconnected" }, |
3513 | | { 0, NULL } |
3514 | | }; |
3515 | | |
3516 | | static const value_string |
3517 | | BACnetUnconfirmedServiceChoice [] = { |
3518 | | { 0, "i-Am"}, |
3519 | | { 1, "i-Have"}, |
3520 | | { 2, "unconfirmedCOVNotification"}, |
3521 | | { 3, "unconfirmedEventNotification"}, |
3522 | | { 4, "unconfirmedPrivateTransfer"}, |
3523 | | { 5, "unconfirmedTextMessage"}, |
3524 | | { 6, "timeSynchronization"}, |
3525 | | { 7, "who-Has"}, |
3526 | | { 8, "who-Is"}, |
3527 | | { 9, "utcTimeSynchronization"}, |
3528 | | { 10, "writeGroup"}, |
3529 | | { 11, "unconfirmedCovNotificationMultiple"}, |
3530 | | { 12, "unconfirmedAuditNotification"}, |
3531 | | { 13, "who-am-I" }, |
3532 | | { 14, "you-are" }, |
3533 | | { 0, NULL} |
3534 | | }; |
3535 | | |
3536 | | static const value_string |
3537 | | BACnetObjectType [] = { |
3538 | | { 0, "analog-input"}, |
3539 | | { 1, "analog-output"}, |
3540 | | { 2, "analog-value"}, |
3541 | | { 3, "binary-input"}, |
3542 | | { 4, "binary-output"}, |
3543 | | { 5, "binary-value"}, |
3544 | | { 6, "calendar"}, |
3545 | | { 7, "command"}, |
3546 | | { 8, "device"}, |
3547 | | { 9, "event-enrollment"}, |
3548 | | { 10, "file"}, |
3549 | | { 11, "group"}, |
3550 | | { 12, "loop"}, |
3551 | | { 13, "multi-state-input"}, |
3552 | | { 14, "multi-state-output"}, |
3553 | | { 15, "notification-class"}, |
3554 | | { 16, "program"}, |
3555 | | { 17, "schedule"}, |
3556 | | { 18, "averaging"}, |
3557 | | { 19, "multi-state-value"}, |
3558 | | { 20, "trend-log"}, |
3559 | | { 21, "life-safety-point"}, |
3560 | | { 22, "life-safety-zone"}, |
3561 | | { 23, "accumulator"}, |
3562 | | { 24, "pulse-converter"}, |
3563 | | { 25, "event-log"}, |
3564 | | { 26, "global-group"}, |
3565 | | { 27, "trend-log-multiple"}, |
3566 | | { 28, "load-control"}, |
3567 | | { 29, "structured-view"}, |
3568 | | { 30, "access-door"}, /* 30-37 added with addanda 135-2008j */ |
3569 | | { 31, "timer"}, |
3570 | | { 32, "access-credential"}, |
3571 | | { 33, "access-point"}, |
3572 | | { 34, "access-rights"}, |
3573 | | { 35, "access-user"}, |
3574 | | { 36, "access-zone"}, |
3575 | | { 37, "credential-data-input"}, |
3576 | | { 38, "network-security"}, |
3577 | | { 39, "bitstring-value"}, /* 39-50 added with addenda 135-2008w */ |
3578 | | { 40, "characterstring-value"}, |
3579 | | { 41, "date-pattern-value"}, |
3580 | | { 42, "date-value"}, |
3581 | | { 43, "datetime-pattern-value"}, |
3582 | | { 44, "datetime-value"}, |
3583 | | { 45, "integer-value"}, |
3584 | | { 46, "large-analog-value"}, |
3585 | | { 47, "octetstring-value"}, |
3586 | | { 48, "positive-integer-value"}, |
3587 | | { 49, "time-pattern-value"}, |
3588 | | { 50, "time-value"}, |
3589 | | { 51, "notification-forwarder"}, |
3590 | | { 52, "alert-enrollment"}, |
3591 | | { 53, "channel"}, |
3592 | | { 54, "lighting-output"}, |
3593 | | { 55, "binary-lighting-output"}, |
3594 | | { 56, "network-port"}, |
3595 | | { 57, "elevator-group"}, |
3596 | | { 58, "escalator"}, |
3597 | | { 59, "lift"}, |
3598 | | { 60, "staging"}, |
3599 | | { 61, "audit-log"}, |
3600 | | { 62, "audit-reporter"}, |
3601 | | { 63, "color"}, |
3602 | | { 64, "color-temperature"}, |
3603 | | { 0, NULL} |
3604 | | /* Enumerated values 0-127 are reserved for definition by ASHRAE. |
3605 | | Enumerated values 128-1023 may be used by others subject to |
3606 | | the procedures and constraints described in Clause 23. */ |
3607 | | }; |
3608 | | static value_string_ext BACnetObjectType_ext = VALUE_STRING_EXT_INIT(BACnetObjectType); |
3609 | | |
3610 | | static const value_string |
3611 | | BACnetObjectTypeAbbrev[] = { |
3612 | | { 0, "AI" }, |
3613 | | { 1, "AO" }, |
3614 | | { 2, "AV" }, |
3615 | | { 3, "BI" }, |
3616 | | { 4, "BO" }, |
3617 | | { 5, "BV" }, |
3618 | | { 6, "CAL" }, |
3619 | | { 7, "CMD" }, |
3620 | | { 8, "DEV" }, |
3621 | | { 9, "EE" }, |
3622 | | { 10, "FV" }, |
3623 | | { 11, "G" }, |
3624 | | { 12, "LP" }, |
3625 | | { 13, "MSI" }, |
3626 | | { 14, "MSO" }, |
3627 | | { 15, "NC" }, |
3628 | | { 16, "PROG" }, |
3629 | | { 17, "SCH" }, |
3630 | | { 18, "AVG" }, |
3631 | | { 19, "MSVV" }, |
3632 | | { 20, "TLV" }, |
3633 | | { 21, "LSP" }, |
3634 | | { 22, "LSZV" }, |
3635 | | { 23, "ACM" }, |
3636 | | { 24, "PC" }, |
3637 | | { 25, "EL" }, |
3638 | | { 26, "GG" }, |
3639 | | { 27, "TLM" }, |
3640 | | { 28, "LCV" }, |
3641 | | { 29, "SV" }, |
3642 | | { 30, "ACD" }, |
3643 | | { 32, "ACC" }, |
3644 | | { 33, "ACP" }, |
3645 | | { 34, "ACR" }, |
3646 | | { 35, "ACU" }, |
3647 | | { 36, "ACZ" }, |
3648 | | { 37, "CDI" }, |
3649 | | { 38, "NS" }, |
3650 | | { 39, "BSV" }, |
3651 | | { 40, "CSV" }, |
3652 | | { 41, "DPV" }, |
3653 | | { 42, "DV" }, |
3654 | | { 43, "DTPV" }, |
3655 | | { 44, "DTV" }, |
3656 | | { 45, "IVV" }, |
3657 | | { 46, "LAV" }, |
3658 | | { 47, "OSV" }, |
3659 | | { 48, "UV" }, |
3660 | | { 49, "TPV" }, |
3661 | | { 50, "TVV" }, |
3662 | | { 51, "NFV" }, |
3663 | | { 52, "AE" }, |
3664 | | { 53, "CH" }, |
3665 | | { 54, "LO" }, |
3666 | | { 55, "BLO" }, |
3667 | | { 56, "NP" }, |
3668 | | { 57, "EG" }, |
3669 | | { 58, "ES" }, |
3670 | | { 59, "L" }, |
3671 | | { 60, "STG" }, |
3672 | | { 61, "ALV" }, |
3673 | | { 62, "AR" }, |
3674 | | { 63, "CO" }, |
3675 | | { 64, "CT" }, |
3676 | | { 0, NULL } |
3677 | | }; |
3678 | | |
3679 | | static const value_string |
3680 | | BACnetEngineeringUnits [] = { |
3681 | | { 0, "Sq Meters"}, |
3682 | | { 1, "Sq Feet"}, |
3683 | | { 2, "Milliamperes"}, |
3684 | | { 3, "Amperes"}, |
3685 | | { 4, "Ohms"}, |
3686 | | { 5, "Volts"}, |
3687 | | { 6, "Kilovolts"}, |
3688 | | { 7, "Megavolts"}, |
3689 | | { 8, "Volt Amperes"}, |
3690 | | { 9, "Kilovolt Amperes"}, |
3691 | | { 10, "Megavolt Amperes"}, |
3692 | | { 11, "Volt Amperes Reactive"}, |
3693 | | { 12, "Kilovolt Amperes Reactive"}, |
3694 | | { 13, "Megavolt Amperes Reactive"}, |
3695 | | { 14, "Degrees Phase"}, |
3696 | | { 15, "Power Factor"}, |
3697 | | { 16, "Joules"}, |
3698 | | { 17, "Kilojoules"}, |
3699 | | { 18, "Watt Hours"}, |
3700 | | { 19, "Kilowatt Hours"}, |
3701 | | { 20, "BTUs"}, |
3702 | | { 21, "Therms"}, |
3703 | | { 22, "Ton Hours"}, |
3704 | | { 23, "Joules Per Kg Dry Air"}, |
3705 | | { 24, "BTUs Per Pound Dry Air"}, |
3706 | | { 25, "Cycles Per Hour"}, |
3707 | | { 26, "Cycles Per Minute"}, |
3708 | | { 27, "Hertz"}, |
3709 | | { 28, "Grams Of Water Per Kilogram Dry Air"}, |
3710 | | { 29, "Relative Humidity"}, |
3711 | | { 30, "Millimeters"}, |
3712 | | { 31, "Meters"}, |
3713 | | { 32, "Inches"}, |
3714 | | { 33, "Feed"}, |
3715 | | { 34, "Watts Per Sq Foot"}, |
3716 | | { 35, "Watts Per Sq meter"}, |
3717 | | { 36, "Lumens"}, |
3718 | | { 37, "Lux"}, |
3719 | | { 38, "Foot Candles"}, |
3720 | | { 39, "Kilograms"}, |
3721 | | { 40, "Pounds Mass"}, |
3722 | | { 41, "Tons"}, |
3723 | | { 42, "Kgs per Second"}, |
3724 | | { 43, "Kgs Per Minute"}, |
3725 | | { 44, "Kgs Per Hour"}, |
3726 | | { 45, "Pounds Mass Per Minute"}, |
3727 | | { 46, "Pounds Mass Per Hour"}, |
3728 | | { 47, "Watt"}, |
3729 | | { 48, "Kilowatts"}, |
3730 | | { 49, "Megawatts"}, |
3731 | | { 50, "BTUs Per Hour"}, |
3732 | | { 51, "Horsepower"}, |
3733 | | { 52, "Tons Refrigeration"}, |
3734 | | { 53, "Pascals"}, |
3735 | | { 54, "Kilopascals"}, |
3736 | | { 55, "Bars"}, |
3737 | | { 56, "Pounds Force Per Square Inch"}, |
3738 | | { 57, "Centimeters Of Water"}, |
3739 | | { 58, "Inches Of Water"}, |
3740 | | { 59, "Millimeters Of Mercury"}, |
3741 | | { 60, "Centimeters Of Mercury"}, |
3742 | | { 61, "Inches Of Mercury"}, |
3743 | | { 62, "Degrees Celsius"}, |
3744 | | { 63, "Degrees Kelvin"}, |
3745 | | { 64, "Degrees Fahrenheit"}, |
3746 | | { 65, "Degree Days Celsius"}, |
3747 | | { 66, "Degree Days Fahrenheit"}, |
3748 | | { 67, "Years"}, |
3749 | | { 68, "Months"}, |
3750 | | { 69, "Weeks"}, |
3751 | | { 70, "Days"}, |
3752 | | { 71, "Hours"}, |
3753 | | { 72, "Minutes"}, |
3754 | | { 73, "Seconds"}, |
3755 | | { 74, "Meters Per Second"}, |
3756 | | { 75, "Kilometers Per Hour"}, |
3757 | | { 76, "Feed Per Second"}, |
3758 | | { 77, "Feet Per Minute"}, |
3759 | | { 78, "Miles Per Hour"}, |
3760 | | { 79, "Cubic Feet"}, |
3761 | | { 80, "Cubic Meters"}, |
3762 | | { 81, "Imperial Gallons"}, |
3763 | | { 82, "Liters"}, |
3764 | | { 83, "US Gallons"}, |
3765 | | { 84, "Cubic Feet Per Minute"}, |
3766 | | { 85, "Cubic Meters Per Second"}, |
3767 | | { 86, "Imperial Gallons Per Minute"}, |
3768 | | { 87, "Liters Per Second"}, |
3769 | | { 88, "Liters Per Minute"}, |
3770 | | { 89, "US Gallons Per Minute"}, |
3771 | | { 90, "Degrees Angular"}, |
3772 | | { 91, "Degrees Celsius Per Hour"}, |
3773 | | { 92, "Degrees Celsius Per Minute"}, |
3774 | | { 93, "Degrees Fahrenheit Per Hour"}, |
3775 | | { 94, "Degrees Fahrenheit Per Minute"}, |
3776 | | { 95, "No Units"}, |
3777 | | { 96, "Parts Per Million"}, |
3778 | | { 97, "Parts Per Billion"}, |
3779 | | { 98, "Percent"}, |
3780 | | { 99, "Percent Per Second"}, |
3781 | | { 100, "Per Minute"}, |
3782 | | { 101, "Per Second"}, |
3783 | | { 102, "Psi Per Degree Fahrenheit"}, |
3784 | | { 103, "Radians"}, |
3785 | | { 104, "Revolutions Per Min"}, |
3786 | | { 105, "Currency1"}, |
3787 | | { 106, "Currency2"}, |
3788 | | { 107, "Currency3"}, |
3789 | | { 108, "Currency4"}, |
3790 | | { 109, "Currency5"}, |
3791 | | { 110, "Currency6"}, |
3792 | | { 111, "Currency7"}, |
3793 | | { 112, "Currency8"}, |
3794 | | { 113, "Currency9"}, |
3795 | | { 114, "Currency10"}, |
3796 | | { 115, "Sq Inches"}, |
3797 | | { 116, "Sq Centimeters"}, |
3798 | | { 117, "BTUs Per Pound"}, |
3799 | | { 118, "Centimeters"}, |
3800 | | { 119, "Pounds Mass Per Second"}, |
3801 | | { 120, "Delta Degrees Fahrenheit"}, |
3802 | | { 121, "Delta Degrees Kelvin"}, |
3803 | | { 122, "Kilohms"}, |
3804 | | { 123, "Megohms"}, |
3805 | | { 124, "Millivolts"}, |
3806 | | { 125, "Kilojoules Per Kg"}, |
3807 | | { 126, "Megajoules"}, |
3808 | | { 127, "Joules Per Degree Kelvin"}, |
3809 | | { 128, "Joules Per Kg Degree Kelvin"}, |
3810 | | { 129, "Kilohertz"}, |
3811 | | { 130, "Megahertz"}, |
3812 | | { 131, "Per Hour"}, |
3813 | | { 132, "Milliwatts"}, |
3814 | | { 133, "Hectopascals"}, |
3815 | | { 134, "Millibars"}, |
3816 | | { 135, "Cubic Meters Per Hour"}, |
3817 | | { 136, "Liters Per Hour"}, |
3818 | | { 137, "KWatt Hours Per Square Meter"}, |
3819 | | { 138, "KWatt Hours Per Square Foot"}, |
3820 | | { 139, "Megajoules Per Square Meter"}, |
3821 | | { 140, "Megajoules Per Square Foot"}, |
3822 | | { 141, "Watts Per Sq Meter Degree Kelvin"}, |
3823 | | { 142, "Cubic Feet Per Second"}, |
3824 | | { 143, "Percent Obstruction Per Foot"}, |
3825 | | { 144, "Percent Obstruction Per Meter"}, |
3826 | | { 145, "milliohms"}, |
3827 | | { 146, "megawatt-hours"}, |
3828 | | { 147, "kilo-btus"}, |
3829 | | { 148, "mega-btus"}, |
3830 | | { 149, "kilojoules-per-kilogram-dry-air"}, |
3831 | | { 150, "megajoules-per-kilogram-dry-air"}, |
3832 | | { 151, "kilojoules-per-degree-Kelvin"}, |
3833 | | { 152, "megajoules-per-degree-Kelvin"}, |
3834 | | { 153, "newton"}, |
3835 | | { 154, "grams-per-second"}, |
3836 | | { 155, "grams-per-minute"}, |
3837 | | { 156, "tons-per-hour"}, |
3838 | | { 157, "kilo-btus-per-hour"}, |
3839 | | { 158, "hundredths-seconds"}, |
3840 | | { 159, "milliseconds"}, |
3841 | | { 160, "newton-meters"}, |
3842 | | { 161, "millimeters-per-second"}, |
3843 | | { 162, "millimeters-per-minute"}, |
3844 | | { 163, "meters-per-minute"}, |
3845 | | { 164, "meters-per-hour"}, |
3846 | | { 165, "cubic-meters-per-minute"}, |
3847 | | { 166, "meters-per-second-per-second"}, |
3848 | | { 167, "amperes-per-meter"}, |
3849 | | { 168, "amperes-per-square-meter"}, |
3850 | | { 169, "ampere-square-meters"}, |
3851 | | { 170, "farads"}, |
3852 | | { 171, "henrys"}, |
3853 | | { 172, "ohm-meters"}, |
3854 | | { 173, "siemens"}, |
3855 | | { 174, "siemens-per-meter"}, |
3856 | | { 175, "teslas"}, |
3857 | | { 176, "volts-per-degree-Kelvin"}, |
3858 | | { 177, "volts-per-meter"}, |
3859 | | { 178, "webers"}, |
3860 | | { 179, "candelas"}, |
3861 | | { 180, "candelas-per-square-meter"}, |
3862 | | { 181, "degrees-Kelvin-per-hour"}, |
3863 | | { 182, "degrees-Kelvin-per-minute"}, |
3864 | | { 183, "joule-seconds"}, |
3865 | | { 184, "radians-per-second"}, |
3866 | | { 185, "square-meters-per-Newton"}, |
3867 | | { 186, "kilograms-per-cubic-meter"}, |
3868 | | { 187, "newton-seconds"}, |
3869 | | { 188, "newtons-per-meter"}, |
3870 | | { 189, "watts-per-meter-per-degree-Kelvin"}, |
3871 | | { 190, "micro-siemens"}, |
3872 | | { 191, "cubic-feet-per-hour"}, |
3873 | | { 192, "us-gallons-per-hour"}, |
3874 | | { 193, "kilometers"}, |
3875 | | { 194, "micrometers"}, |
3876 | | { 195, "grams"}, |
3877 | | { 196, "milligrams"}, |
3878 | | { 197, "milliliters"}, |
3879 | | { 198, "milliliters-per-second"}, |
3880 | | { 199, "decibels"}, |
3881 | | { 200, "decibels-millivolt"}, |
3882 | | { 201, "decibels-volt"}, |
3883 | | { 202, "millisiemens"}, |
3884 | | { 203, "watt-hours-reactive"}, |
3885 | | { 204, "kilowatt-hours-reactive"}, |
3886 | | { 205, "megawatt-hours-reactive"}, |
3887 | | { 206, "millimeters-of-water"}, |
3888 | | { 207, "per-mille"}, |
3889 | | { 208, "grams-per-gram"}, |
3890 | | { 209, "kilograms-per-kilogram"}, |
3891 | | { 210, "grams-per-kilogram"}, |
3892 | | { 211, "milligrams-per-gram"}, |
3893 | | { 212, "milligrams-per-kilogram"}, |
3894 | | { 213, "grams-per-milliliter"}, |
3895 | | { 214, "grams-per-liter"}, |
3896 | | { 215, "milligrams-per-liter"}, |
3897 | | { 216, "micrograms-per-liter"}, |
3898 | | { 217, "grams-per-cubic-meter"}, |
3899 | | { 218, "milligrams-per-cubic-meter"}, |
3900 | | { 219, "micrograms-per-cubic-meter"}, |
3901 | | { 220, "nanograms-per-cubic-meter"}, |
3902 | | { 221, "grams-per-cubic-centimeter"}, |
3903 | | { 222, "becquerels"}, |
3904 | | { 223, "kilobecquerels"}, |
3905 | | { 224, "megabecquerels"}, |
3906 | | { 225, "gray"}, |
3907 | | { 226, "milligray"}, |
3908 | | { 227, "microgray"}, |
3909 | | { 228, "sieverts"}, |
3910 | | { 229, "millisieverts"}, |
3911 | | { 230, "microsieverts"}, |
3912 | | { 231, "microsieverts-per-hour"}, |
3913 | | { 232, "decibels-a"}, |
3914 | | { 233, "nephelometric-turbidity-unit"}, |
3915 | | { 234, "pH"}, |
3916 | | { 235, "grams-per-square-meter"}, |
3917 | | { 236, "minutes-per-degree-kelvin"}, |
3918 | | { 237, "ohm-meter-squared-per-meter"}, |
3919 | | { 238, "ampere-seconds"}, |
3920 | | { 239, "volt-ampere-hours"}, |
3921 | | { 240, "kilovolt-ampere-hours"}, |
3922 | | { 241, "megavolt-ampere-hours"}, |
3923 | | { 242, "volt-ampere-hours-reactive"}, |
3924 | | { 243, "kilovolt-ampere-hours-reactive"}, |
3925 | | { 244, "megavolt-ampere-hours-reactive"}, |
3926 | | { 245, "volt-square-hours"}, |
3927 | | { 246, "ampere-square-hours"}, |
3928 | | { 247, "joule-per-hours"}, |
3929 | | { 248, "cubic-feet-per-day"}, |
3930 | | { 249, "cubic-meters-per-day"}, |
3931 | | { 250, "watt-hours-per-cubic-meter"}, |
3932 | | { 251, "joules-per-cubic-meter"}, |
3933 | | { 252, "mole-percent"}, |
3934 | | { 253, "pascal-seconds"}, |
3935 | | { 254, "million-standard-cubic-feet-per-minute"}, |
3936 | | { 255, "unassigned-unit-value-255"}, |
3937 | | { 47808, "standard-cubic-feet-per-day"}, |
3938 | | { 47809, "million-standard-cubic-feet-per-day"}, |
3939 | | { 47810, "thousand-cubic-feet-per-day"}, |
3940 | | { 47811, "thousand-standard-cubic-feet-per-day"}, |
3941 | | { 47812, "pounds-mass-per-day"}, |
3942 | | { 47813, "reserved-unit-47813"}, |
3943 | | { 47814, "millirems"}, |
3944 | | { 47815, "millirems-per-hour"}, |
3945 | | { 47816, "degrees-lovibond"}, |
3946 | | { 47817, "alcohol-by-volume"}, |
3947 | | { 47818, "international-bittering-units"}, |
3948 | | { 47819, "european-bitterness-units"}, |
3949 | | { 47820, "degrees-plato"}, |
3950 | | { 47821, "specific-gravity"}, |
3951 | | { 47822, "european-brewing-convention"}, |
3952 | | { 0, NULL} |
3953 | | /* Enumerated values 0-255 are reserved for definition by ASHRAE. |
3954 | | Enumerated values 256-65535 may be used by others subject to |
3955 | | the procedures and constraints described in Clause 23. */ |
3956 | | }; |
3957 | | |
3958 | | static const value_string |
3959 | | BACnetErrorCode [] = { |
3960 | | { 0, "other"}, |
3961 | | { 1, "authentication-failed"}, |
3962 | | { 2, "configuration-in-progress"}, |
3963 | | { 3, "device-busy"}, |
3964 | | { 4, "dynamic-creation-not-supported"}, |
3965 | | { 5, "file-access-denied"}, |
3966 | | { 6, "incompatible-security-levels"}, |
3967 | | { 7, "inconsistent-parameters"}, |
3968 | | { 8, "inconsistent-selection-criterion"}, |
3969 | | { 9, "invalid-data-type"}, |
3970 | | { 10, "invalid-file-access-method"}, |
3971 | | { 11, "invalid-file-start-position"}, |
3972 | | { 12, "invalid-operator-name"}, |
3973 | | { 13, "invalid-parameter-data-type"}, |
3974 | | { 14, "invalid-time-stamp"}, |
3975 | | { 15, "key-generation-error"}, |
3976 | | { 16, "missing-required-parameter"}, |
3977 | | { 17, "no-objects-of-specified-type"}, |
3978 | | { 18, "no-space-for-object"}, |
3979 | | { 19, "no-space-to-add-list-element"}, |
3980 | | { 20, "no-space-to-write-property"}, |
3981 | | { 21, "no-vt-sessions-available"}, |
3982 | | { 22, "property-is-not-a-list"}, |
3983 | | { 23, "object-deletion-not-permitted"}, |
3984 | | { 24, "object-identifier-already-exists"}, |
3985 | | { 25, "operational-problem"}, |
3986 | | { 26, "password-failure"}, |
3987 | | { 27, "read-access-denied"}, |
3988 | | { 28, "security-not-supported"}, |
3989 | | { 29, "service-request-denied"}, |
3990 | | { 30, "timeout"}, |
3991 | | { 31, "unknown-object"}, |
3992 | | { 32, "unknown-property"}, |
3993 | | { 33, "removed enumeration"}, |
3994 | | { 34, "unknown-vt-class"}, |
3995 | | { 35, "unknown-vt-session"}, |
3996 | | { 36, "unsupported-object-type"}, |
3997 | | { 37, "value-out-of-range"}, |
3998 | | { 38, "vt-session-already-closed"}, |
3999 | | { 39, "vt-session-termination-failure"}, |
4000 | | { 40, "write-access-denied"}, |
4001 | | { 41, "character-set-not-supported"}, |
4002 | | { 42, "invalid-array-index"}, |
4003 | | { 43, "cov-subscription-failed"}, |
4004 | | { 44, "not-cov-property"}, |
4005 | | { 45, "optional-functionality-not-supported"}, |
4006 | | { 46, "invalid-configuration-data"}, |
4007 | | { 47, "datatype-not-supported"}, |
4008 | | { 48, "duplicate-name"}, |
4009 | | { 49, "duplicate-object-id"}, |
4010 | | { 50, "property-is-not-an-array"}, |
4011 | | { 51, "abort - buffer - overflow" }, |
4012 | | { 52, "abort - invalid - apdu - in - this - state" }, |
4013 | | { 53, "abort - preempted - by - higher - priority - task" }, |
4014 | | { 54, "abort - segmentation - not - supported" }, |
4015 | | { 55, "abort - proprietary" }, |
4016 | | { 56, "abort - other" }, |
4017 | | { 57, "invalid - tag" }, |
4018 | | { 58, "network - down" }, |
4019 | | { 59, "reject - buffer - overflow" }, |
4020 | | { 60, "reject - inconsistent - parameters" }, |
4021 | | { 61, "reject - invalid - parameter - data - type" }, |
4022 | | { 62, "reject - invalid - tag" }, |
4023 | | { 63, "reject - missing - required - parameter" }, |
4024 | | { 64, "reject - parameter - out - of - range" }, |
4025 | | { 65, "reject - too - many - arguments" }, |
4026 | | { 66, "reject - undefined - enumeration" }, |
4027 | | { 67, "reject - unrecognized - service" }, |
4028 | | { 68, "reject - proprietary" }, |
4029 | | { 69, "reject - other" }, |
4030 | | { 70, "unknown - device" }, |
4031 | | { 71, "unknown - route" }, |
4032 | | { 72, "value - not - initialized" }, |
4033 | | { 73, "invalid-event-state"}, |
4034 | | { 74, "no-alarm-configured"}, |
4035 | | { 75, "log-buffer-full"}, |
4036 | | { 76, "logged-value-purged"}, |
4037 | | { 77, "no-property-specified"}, |
4038 | | { 78, "not-configured-for-triggered-logging"}, |
4039 | | { 79, "unknown-subscription"}, |
4040 | | { 80, "parameter-out-of-range"}, |
4041 | | { 81, "list-element-not-found"}, |
4042 | | { 82, "busy"}, |
4043 | | { 83, "communication-disabled"}, |
4044 | | { 84, "success"}, |
4045 | | { 85, "access-denied"}, |
4046 | | { 86, "bad-destination-address"}, |
4047 | | { 87, "bad-destination-device-id"}, |
4048 | | { 88, "bad-signature"}, |
4049 | | { 89, "bad-source-address"}, |
4050 | | { 90, "bad-timestamp"}, |
4051 | | { 91, "cannot-use-key"}, |
4052 | | { 92, "cannot-verify-message-id"}, |
4053 | | { 93, "correct-key-revision"}, |
4054 | | { 94, "destination-device-id-required"}, |
4055 | | { 95, "duplicate-message"}, |
4056 | | { 96, "encryption-not-configured"}, |
4057 | | { 97, "encryption-required"}, |
4058 | | { 98, "incorrect-key"}, |
4059 | | { 99, "invalid-key-data"}, |
4060 | | { 100, "key-update-in-progress"}, |
4061 | | { 101, "malformed-message"}, |
4062 | | { 102, "not-key-server"}, |
4063 | | { 103, "security-not-configured"}, |
4064 | | { 104, "source-security-required"}, |
4065 | | { 105, "too-many-keys"}, |
4066 | | { 106, "unknown-authentication-type"}, |
4067 | | { 107, "unknown-key"}, |
4068 | | { 108, "unknown-key-revision"}, |
4069 | | { 109, "unknown-source-message"}, |
4070 | | { 110, "not-router-to-dnet"}, |
4071 | | { 111, "router-busy"}, |
4072 | | { 112, "unknown-network-message"}, |
4073 | | { 113, "message-too-long"}, |
4074 | | { 114, "security-error"}, |
4075 | | { 115, "addressing-error"}, |
4076 | | { 116, "write-bdt-failed"}, |
4077 | | { 117, "read-bdt-failed"}, |
4078 | | { 118, "register-foreign-device-failed"}, |
4079 | | { 119, "read-fdt-failed"}, |
4080 | | { 120, "delete-fdt-entry-failed"}, |
4081 | | { 121, "distribute-broadcast-failed"}, |
4082 | | { 122, "unknown-file-size"}, |
4083 | | { 123, "abort-apdu-too-long"}, |
4084 | | { 124, "abort-application-exceeded-reply-time"}, |
4085 | | { 125, "abort-out-of-resources"}, |
4086 | | { 126, "abort-tsm-timeout"}, |
4087 | | { 127, "abort-window-size-out-of-range"}, |
4088 | | { 128, "file-full"}, |
4089 | | { 129, "inconsistent-configuration"}, |
4090 | | { 130, "inconsistent-object-type"}, |
4091 | | { 131, "internal-error"}, |
4092 | | { 132, "not-configured"}, |
4093 | | { 133, "out-of-memory"}, |
4094 | | { 134, "value-too-long"}, |
4095 | | { 135, "abort-insufficient-security"}, |
4096 | | { 136, "abort-security-error"}, |
4097 | | { 137, "duplicate-entry"}, |
4098 | | { 138, "invalid-value-in-this-state"}, |
4099 | | { 139, "invalid-operation-in-this-state"}, |
4100 | | { 140, "list-item-not-numbered"}, |
4101 | | { 141, "list-item-not-timestamped"}, |
4102 | | { 142, "invalid-data-encoding"}, |
4103 | | { 143, "bvlc-function-unknown"}, |
4104 | | { 144, "bvlc-proprietary-function-unknown"}, |
4105 | | { 145, "header-encoding-error"}, |
4106 | | { 146, "header-not-understood"}, |
4107 | | { 147, "message-incomplete"}, |
4108 | | { 148, "not-a-bacnet-sc-hub"}, |
4109 | | { 149, "payload-expected"}, |
4110 | | { 150, "unexpected-data"}, |
4111 | | { 151, "node-duplicate-vmac"}, |
4112 | | { 152, "http-unexpected-response-code"}, |
4113 | | { 153, "http-no-upgrade"}, |
4114 | | { 154, "http-resource-not-local"}, |
4115 | | { 155, "http-proxy-authentication-failed"}, |
4116 | | { 156, "http-response-timeout"}, |
4117 | | { 157, "http-response-syntax-error"}, |
4118 | | { 158, "http-response-value-error"}, |
4119 | | { 159, "http-response-missing-header"}, |
4120 | | { 160, "http-websocket-header-error"}, |
4121 | | { 161, "http-upgrade-required"}, |
4122 | | { 162, "http-upgrade-error"}, |
4123 | | { 163, "http-temporary-unavailable"}, |
4124 | | { 164, "http-not-a-server"}, |
4125 | | { 165, "http-error"}, |
4126 | | { 166, "websocket-scheme-not-supported"}, |
4127 | | { 167, "websocket-unknown-control-message"}, |
4128 | | { 168, "websocket-close-error"}, |
4129 | | { 169, "websocket-closed-by-peer"}, |
4130 | | { 170, "websocket-endpoint-leaves"}, |
4131 | | { 171, "websocket-protocol-error"}, |
4132 | | { 172, "websocket-data-not-accepted"}, |
4133 | | { 173, "websocket-closed-abnormally"}, |
4134 | | { 174, "websocket-data-inconsistent"}, |
4135 | | { 175, "websocket-data-against-policy"}, |
4136 | | { 176, "websocket-frame-too-long"}, |
4137 | | { 177, "websocket-extension-missing"}, |
4138 | | { 178, "websocket-request-unavailable"}, |
4139 | | { 179, "websocket-error"}, |
4140 | | { 180, "tls-client-certificate-error"}, |
4141 | | { 181, "tls-server-certificate-error"}, |
4142 | | { 182, "tls-client-authentication-failed"}, |
4143 | | { 183, "tls-server-authentication-failed"}, |
4144 | | { 184, "tls-client-certificate-expired"}, |
4145 | | { 185, "tls-server-certificate-expired"}, |
4146 | | { 186, "tls-client-certificate-revoked"}, |
4147 | | { 187, "tls-server-certificate-revoked"}, |
4148 | | { 188, "tls-error"}, |
4149 | | { 189, "dns-unavailable"}, |
4150 | | { 190, "dns-name-resolution-failed"}, |
4151 | | { 191, "dns-resolver-failure"}, |
4152 | | { 192, "dns-error"}, |
4153 | | { 193, "tcp-connect-timeout"}, |
4154 | | { 194, "tcp-connection-refused"}, |
4155 | | { 195, "tcp-closed-by-local"}, |
4156 | | { 196, "tcp-closed-other"}, |
4157 | | { 197, "tcp-error"}, |
4158 | | { 198, "ip-address-not-reachable"}, |
4159 | | { 199, "ip-error"}, |
4160 | | { 200, "certificate-expired"}, |
4161 | | { 201, "certificate-invalid"}, |
4162 | | { 202, "certificate-malformed"}, |
4163 | | { 203, "certificate-revoked"}, |
4164 | | { 204, "unknown-key"}, |
4165 | | { 205, "referenced-port-in-error"}, |
4166 | | { 206, "not-enabled"}, |
4167 | | { 207, "adjust-scope-required"}, |
4168 | | { 208, "auth-scope-required"}, |
4169 | | { 209, "bind-scope-required"}, |
4170 | | { 210, "config-scope-required"}, |
4171 | | { 211, "control-scope-required"}, |
4172 | | { 212, "extended-scope-required"}, |
4173 | | { 213, "incorrect-client"}, |
4174 | | { 214, "install-scope-required"}, |
4175 | | { 215, "insufficient-scope"}, |
4176 | | { 216, "no-default-scope"}, |
4177 | | { 217, "no-policy"}, |
4178 | | { 218, "revoked-token"}, |
4179 | | { 219, "override-scope-required"}, |
4180 | | { 220, "inactive-token"}, |
4181 | | { 221, "unknown-audience"}, |
4182 | | { 222, "unknown-client"}, |
4183 | | { 223, "unknown-scope"}, |
4184 | | { 224, "view-scope-required"}, |
4185 | | { 225, "incorrect-audience"}, |
4186 | | { 226, "incorrect-client-origin"}, |
4187 | | { 227, "invalid-array-size"}, |
4188 | | { 228, "incorrect-issuer"}, |
4189 | | { 229, "invalid-token"}, |
4190 | | { 0, NULL} |
4191 | | /* Enumerated values 0-255 are reserved for definition by ASHRAE. |
4192 | | Enumerated values 256-65535 may be used by others subject to the |
4193 | | procedures and constraints described in Clause 23. */ |
4194 | | }; |
4195 | | static value_string_ext BACnetErrorCode_ext = VALUE_STRING_EXT_INIT(BACnetErrorCode); |
4196 | | |
4197 | | static const value_string |
4198 | | BACnetPropertyIdentifier [] = { |
4199 | | { 0, "acked-transition"}, |
4200 | | { 1, "ack-required"}, |
4201 | | { 2, "action"}, |
4202 | | { 3, "action-text"}, |
4203 | | { 4, "active-text"}, |
4204 | | { 5, "active-vt-session"}, |
4205 | | { 6, "alarm-value"}, |
4206 | | { 7, "alarm-values"}, |
4207 | | { 8, "all"}, |
4208 | | { 9, "all-writes-successful"}, |
4209 | | { 10, "apdu-segment-timeout"}, |
4210 | | { 11, "apdu-timeout"}, |
4211 | | { 12, "application-software-version"}, |
4212 | | { 13, "archive"}, |
4213 | | { 14, "bias"}, |
4214 | | { 15, "change-of-state-count"}, |
4215 | | { 16, "change-of-state-time"}, |
4216 | | { 17, "notification-class"}, |
4217 | | { 18, "the property in this place was deleted"}, |
4218 | | { 19, "controlled-variable-reference"}, |
4219 | | { 20, "controlled-variable-units"}, |
4220 | | { 21, "controlled-variable-value"}, |
4221 | | { 22, "cov-increment"}, |
4222 | | { 23, "datelist"}, |
4223 | | { 24, "daylights-savings-status"}, |
4224 | | { 25, "deadband"}, |
4225 | | { 26, "derivative-constant"}, |
4226 | | { 27, "derivative-constant-units"}, |
4227 | | { 28, "description"}, |
4228 | | { 29, "description-of-halt"}, |
4229 | | { 30, "device-address-binding"}, |
4230 | | { 31, "device-type"}, |
4231 | | { 32, "effective-period"}, |
4232 | | { 33, "elapsed-active-time"}, |
4233 | | { 34, "error-limit"}, |
4234 | | { 35, "event-enable"}, |
4235 | | { 36, "event-state"}, |
4236 | | { 37, "event-type"}, |
4237 | | { 38, "exception-schedule"}, |
4238 | | { 39, "fault-values"}, |
4239 | | { 40, "feedback-value"}, |
4240 | | { 41, "file-access-method"}, |
4241 | | { 42, "file-size"}, |
4242 | | { 43, "file-type"}, |
4243 | | { 44, "firmware-revision"}, |
4244 | | { 45, "high-limit"}, |
4245 | | { 46, "inactive-text"}, |
4246 | | { 47, "in-process"}, |
4247 | | { 48, "instance-of"}, |
4248 | | { 49, "integral-constant"}, |
4249 | | { 50, "integral-constant-units"}, |
4250 | | { 51, "issue-confirmed-notifications"}, |
4251 | | { 52, "limit-enable"}, |
4252 | | { 53, "list-of-group-members"}, |
4253 | | { 54, "list-of-object-property-references"}, |
4254 | | { 55, "list-of-session-keys"}, |
4255 | | { 56, "local-date"}, |
4256 | | { 57, "local-time"}, |
4257 | | { 58, "location"}, |
4258 | | { 59, "low-limit"}, |
4259 | | { 60, "manipulated-variable-reference"}, |
4260 | | { 61, "maximum-output"}, |
4261 | | { 62, "max-apdu-length-accepted"}, |
4262 | | { 63, "max-info-frames"}, |
4263 | | { 64, "max-master"}, |
4264 | | { 65, "max-pres-value"}, |
4265 | | { 66, "minimum-off-time"}, |
4266 | | { 67, "minimum-on-time"}, |
4267 | | { 68, "minimum-output"}, |
4268 | | { 69, "min-pres-value"}, |
4269 | | { 70, "model-name"}, |
4270 | | { 71, "modification-date"}, |
4271 | | { 72, "notify-type"}, |
4272 | | { 73, "number-of-APDU-retries"}, |
4273 | | { 74, "number-of-states"}, |
4274 | | { 75, "object-identifier"}, |
4275 | | { 76, "object-list"}, |
4276 | | { 77, "object-name"}, |
4277 | | { 78, "object-property-reference"}, |
4278 | | { 79, "object-type"}, |
4279 | | { 80, "optional"}, |
4280 | | { 81, "out-of-service"}, |
4281 | | { 82, "output-units"}, |
4282 | | { 83, "event-parameters"}, |
4283 | | { 84, "polarity"}, |
4284 | | { 85, "present-value"}, |
4285 | | { 86, "priority"}, |
4286 | | { 87, "priority-array"}, |
4287 | | { 88, "priority-for-writing"}, |
4288 | | { 89, "process-identifier"}, |
4289 | | { 90, "program-change"}, |
4290 | | { 91, "program-location"}, |
4291 | | { 92, "program-state"}, |
4292 | | { 93, "proportional-constant"}, |
4293 | | { 94, "proportional-constant-units"}, |
4294 | | { 95, "protocol-conformance-class"}, |
4295 | | { 96, "protocol-object-types-supported"}, |
4296 | | { 97, "protocol-services-supported"}, |
4297 | | { 98, "protocol-version"}, |
4298 | | { 99, "read-only"}, |
4299 | | { 100, "reason-for-halt"}, |
4300 | | { 101, "recipient"}, |
4301 | | { 102, "recipient-list"}, |
4302 | | { 103, "reliability"}, |
4303 | | { 104, "relinquish-default"}, |
4304 | | { 105, "required"}, |
4305 | | { 106, "resolution"}, |
4306 | | { 107, "segmentation-supported"}, |
4307 | | { 108, "setpoint"}, |
4308 | | { 109, "setpoint-reference"}, |
4309 | | { 110, "state-text"}, |
4310 | | { 111, "status-flags"}, |
4311 | | { 112, "system-status"}, |
4312 | | { 113, "time-delay"}, |
4313 | | { 114, "time-of-active-time-reset"}, |
4314 | | { 115, "time-of-state-count-reset"}, |
4315 | | { 116, "time-synchronization-recipients"}, |
4316 | | { 117, "units"}, |
4317 | | { 118, "update-interval"}, |
4318 | | { 119, "utc-offset"}, |
4319 | | { 120, "vendor-identifier"}, |
4320 | | { 121, "vendor-name"}, |
4321 | | { 122, "vt-class-supported"}, |
4322 | | { 123, "weekly-schedule"}, |
4323 | | { 124, "attempted-samples"}, |
4324 | | { 125, "average-value"}, |
4325 | | { 126, "buffer-size"}, |
4326 | | { 127, "client-cov-increment"}, |
4327 | | { 128, "cov-resubscription-interval"}, |
4328 | | { 129, "current-notify-time"}, |
4329 | | { 130, "event-time-stamp"}, |
4330 | | { 131, "log-buffer"}, |
4331 | | { 132, "log-device-object-property"}, |
4332 | | { 133, "enable"}, /* per ANSI/ASHRAE 135-2004 addendum B */ |
4333 | | { 134, "log-interval"}, |
4334 | | { 135, "maximum-value"}, |
4335 | | { 136, "minimum-value"}, |
4336 | | { 137, "notification-threshold"}, |
4337 | | { 138, "previous-notify-time"}, |
4338 | | { 139, "protocol-revision"}, |
4339 | | { 140, "records-since-notification"}, |
4340 | | { 141, "record-count"}, |
4341 | | { 142, "start-time"}, |
4342 | | { 143, "stop-time"}, |
4343 | | { 144, "stop-when-full"}, |
4344 | | { 145, "total-record-count"}, |
4345 | | { 146, "valid-samples"}, |
4346 | | { 147, "window-interval"}, |
4347 | | { 148, "window-samples"}, |
4348 | | { 149, "maximum-value-time-stamp"}, |
4349 | | { 150, "minimum-value-time-stamp"}, |
4350 | | { 151, "variance-value"}, |
4351 | | { 152, "active-cov-subscriptions"}, |
4352 | | { 153, "backup-failure-timeout"}, |
4353 | | { 154, "configuration-files"}, |
4354 | | { 155, "database-revision"}, |
4355 | | { 156, "direct-reading"}, |
4356 | | { 157, "last-restore-time"}, |
4357 | | { 158, "maintenance-required"}, |
4358 | | { 159, "member-of"}, |
4359 | | { 160, "mode"}, |
4360 | | { 161, "operation-expected"}, |
4361 | | { 162, "setting"}, |
4362 | | { 163, "silenced"}, |
4363 | | { 164, "tracking-value"}, |
4364 | | { 165, "zone-members"}, |
4365 | | { 166, "life-safety-alarm-values"}, |
4366 | | { 167, "max-segments-accepted"}, |
4367 | | { 168, "profile-name"}, |
4368 | | { 169, "auto-slave-discovery"}, |
4369 | | { 170, "manual-slave-address-binding"}, |
4370 | | { 171, "slave-address-binding"}, |
4371 | | { 172, "slave-proxy-enable"}, |
4372 | | { 173, "last-notify-record"}, /* bug 4117 */ |
4373 | | { 174, "schedule-default"}, |
4374 | | { 175, "accepted-modes"}, |
4375 | | { 176, "adjust-value"}, |
4376 | | { 177, "count"}, |
4377 | | { 178, "count-before-change"}, |
4378 | | { 179, "count-change-time"}, |
4379 | | { 180, "cov-period"}, |
4380 | | { 181, "input-reference"}, |
4381 | | { 182, "limit-monitoring-interval"}, |
4382 | | { 183, "logging-object"}, |
4383 | | { 184, "logging-record"}, |
4384 | | { 185, "prescale"}, |
4385 | | { 186, "pulse-rate"}, |
4386 | | { 187, "scale"}, |
4387 | | { 188, "scale-factor"}, |
4388 | | { 189, "update-time"}, |
4389 | | { 190, "value-before-change"}, |
4390 | | { 191, "value-set"}, |
4391 | | { 192, "value-change-time"}, |
4392 | | { 193, "align-intervals"}, |
4393 | | { 194, "group-member-names"}, |
4394 | | { 195, "interval-offset"}, |
4395 | | { 196, "last-restart-reason"}, |
4396 | | { 197, "logging-type"}, |
4397 | | { 198, "member-status-flags"}, |
4398 | | { 199, "notification-period"}, |
4399 | | { 200, "previous-notify-record"}, |
4400 | | { 201, "requested-update-interval"}, |
4401 | | { 202, "restart-notification-recipients"}, |
4402 | | { 203, "time-of-device-restart"}, |
4403 | | { 204, "time-synchronization-interval"}, |
4404 | | { 205, "trigger"}, |
4405 | | { 206, "UTC-time-synchronization-recipients"}, |
4406 | | { 207, "node-subtype"}, |
4407 | | { 208, "node-type"}, |
4408 | | { 209, "structured-object-list"}, |
4409 | | { 210, "subordinate-annotations"}, |
4410 | | { 211, "subordinate-list"}, |
4411 | | { 212, "actual-shed-level"}, |
4412 | | { 213, "duty-window"}, |
4413 | | { 214, "expected-shed-level"}, |
4414 | | { 215, "full-duty-baseline"}, |
4415 | | { 216, "node-subtype"}, |
4416 | | { 217, "node-type"}, |
4417 | | { 218, "requested-shed-level"}, |
4418 | | { 219, "shed-duration"}, |
4419 | | { 220, "shed-level-descriptions"}, |
4420 | | { 221, "shed-levels"}, |
4421 | | { 222, "state-description"}, |
4422 | | /* enumeration values 223-225 are unassigned */ |
4423 | | { 226, "door-alarm-state"}, |
4424 | | { 227, "door-extended-pulse-time"}, |
4425 | | { 228, "door-members"}, |
4426 | | { 229, "door-open-too-long-time"}, |
4427 | | { 230, "door-pulse-time"}, |
4428 | | { 231, "door-status"}, |
4429 | | { 232, "door-unlock-delay-time"}, |
4430 | | { 233, "lock-status"}, |
4431 | | { 234, "masked-alarm-values"}, |
4432 | | { 235, "secured-status"}, |
4433 | | /* enumeration values 236-243 are unassigned */ |
4434 | | { 244, "absentee-limit"}, /* added with addenda 135-2008j */ |
4435 | | { 245, "access-alarm-events"}, |
4436 | | { 246, "access-doors"}, |
4437 | | { 247, "access-event"}, |
4438 | | { 248, "access-event-authentication-factor"}, |
4439 | | { 249, "access-event-credential"}, |
4440 | | { 250, "access-event-time"}, |
4441 | | { 251, "access-transaction-events"}, |
4442 | | { 252, "accompaniment"}, |
4443 | | { 253, "accompaniment-time"}, |
4444 | | { 254, "activation-time"}, |
4445 | | { 255, "active-authentication-policy"}, |
4446 | | { 256, "assigned-access-rights"}, |
4447 | | { 257, "authentication-factors"}, |
4448 | | { 258, "authentication-policy-list"}, |
4449 | | { 259, "authentication-policy-names"}, |
4450 | | { 260, "authentication-status"}, |
4451 | | { 261, "authorization-mode"}, |
4452 | | { 262, "belongs-to"}, |
4453 | | { 263, "credential-disable"}, |
4454 | | { 264, "credential-status"}, |
4455 | | { 265, "credentials"}, |
4456 | | { 266, "credentials-in-zone"}, |
4457 | | { 267, "days-remaining"}, |
4458 | | { 268, "entry-points"}, |
4459 | | { 269, "exit-points"}, |
4460 | | { 270, "expiration-time"}, |
4461 | | { 271, "extended-time-enable"}, |
4462 | | { 272, "failed-attempt-events"}, |
4463 | | { 273, "failed-attempts"}, |
4464 | | { 274, "failed-attempts-time"}, |
4465 | | { 275, "last-access-event"}, |
4466 | | { 276, "last-access-point"}, |
4467 | | { 277, "last-credential-added"}, |
4468 | | { 278, "last-credential-added-time"}, |
4469 | | { 279, "last-credential-removed"}, |
4470 | | { 280, "last-credential-removed-time"}, |
4471 | | { 281, "last-use-time"}, |
4472 | | { 282, "lockout"}, |
4473 | | { 283, "lockout-relinquish-time"}, |
4474 | | { 284, "master-exemption"}, |
4475 | | { 285, "max-failed-attempts"}, |
4476 | | { 286, "members"}, |
4477 | | { 287, "muster-point"}, |
4478 | | { 288, "negative-access-rules"}, |
4479 | | { 289, "number-of-authentication-policies"}, |
4480 | | { 290, "occupancy-count"}, |
4481 | | { 291, "occupancy-count-adjust"}, |
4482 | | { 292, "occupancy-count-enable"}, |
4483 | | { 293, "occupancy-exemption"}, |
4484 | | { 294, "occupancy-lower-limit"}, |
4485 | | { 295, "occupancy-lower-limit-enforced"}, |
4486 | | { 296, "occupancy-state"}, |
4487 | | { 297, "occupancy-upper-limit"}, |
4488 | | { 298, "occupancy-upper-limit-enforced"}, |
4489 | | { 299, "passback-exemption"}, |
4490 | | { 300, "passback-mode"}, |
4491 | | { 301, "passback-timeout"}, |
4492 | | { 302, "positive-access-rules"}, |
4493 | | { 303, "reason-for-disable"}, |
4494 | | { 304, "supported-formats"}, |
4495 | | { 305, "supported-format-classes"}, |
4496 | | { 306, "threat-authority"}, |
4497 | | { 307, "threat-level"}, |
4498 | | { 308, "trace-flag"}, |
4499 | | { 309, "transaction-notification-class"}, |
4500 | | { 310, "user-external-identifier"}, |
4501 | | { 311, "user-information-reference"}, |
4502 | | /* enumeration values 312-316 are unassigned */ |
4503 | | { 317, "user-name"}, |
4504 | | { 318, "user-type"}, |
4505 | | { 319, "uses-remaining"}, |
4506 | | { 320, "zone-from"}, |
4507 | | { 321, "zone-to"}, |
4508 | | { 322, "access-event-tag"}, |
4509 | | { 323, "global-identifier"}, |
4510 | | /* enumeration values 324-325 reserved for future addenda */ |
4511 | | { 326, "verification-time"}, |
4512 | | { 327, "base-device-security-policy"}, |
4513 | | { 328, "distribution-key-revision"}, |
4514 | | { 329, "do-not-hide"}, |
4515 | | { 330, "key-sets"}, |
4516 | | { 331, "last-key-server"}, |
4517 | | { 332, "network-access-security-policies"}, |
4518 | | { 333, "packet-reorder-time"}, |
4519 | | { 334, "security-pdu-timeout"}, |
4520 | | { 335, "security-time-window"}, |
4521 | | { 336, "supported-security-algorithms"}, |
4522 | | { 337, "update-key-set-timeout"}, |
4523 | | { 338, "backup-and-restore-state"}, |
4524 | | { 339, "backup-preparation-time"}, |
4525 | | { 340, "restore-completion-time"}, |
4526 | | { 341, "restore-preparation-time"}, |
4527 | | { 342, "bit-mask"}, /* addenda 135-2008w */ |
4528 | | { 343, "bit-text"}, |
4529 | | { 344, "is-utc"}, |
4530 | | { 345, "group-members"}, |
4531 | | { 346, "group-member-names"}, |
4532 | | { 347, "member-status-flags"}, |
4533 | | { 348, "requested-update-interval"}, |
4534 | | { 349, "covu-period"}, |
4535 | | { 350, "covu-recipients"}, |
4536 | | { 351, "event-message-texts"}, |
4537 | | { 352, "event-message-texts-config"}, |
4538 | | { 353, "event-detection-enable"}, |
4539 | | { 354, "event-algorithm-inhibit"}, |
4540 | | { 355, "event-algorithm-inhibit-ref"}, |
4541 | | { 356, "time-delay-normal"}, |
4542 | | { 357, "reliability-evaluation-inhibit"}, |
4543 | | { 358, "fault-parameters"}, |
4544 | | { 359, "fault-type"}, |
4545 | | { 360, "local-forwarding-only"}, |
4546 | | { 361, "process-identifier-filter"}, |
4547 | | { 362, "subscribed-recipients"}, |
4548 | | { 363, "port-filter"}, |
4549 | | { 364, "authorization-exemptions"}, |
4550 | | { 365, "allow-group-delay-inhibit"}, |
4551 | | { 366, "channel-number"}, |
4552 | | { 367, "control-groups"}, |
4553 | | { 368, "execution-delay"}, |
4554 | | { 369, "last-priority"}, |
4555 | | { 370, "write-status"}, |
4556 | | { 371, "property-list"}, |
4557 | | { 372, "serial-number"}, |
4558 | | { 373, "blink-warn-enable"}, |
4559 | | { 374, "default-fade-time"}, |
4560 | | { 375, "default-ramp-rate"}, |
4561 | | { 376, "default-step-increment"}, |
4562 | | { 377, "egress-time"}, |
4563 | | { 378, "in-progress"}, |
4564 | | { 379, "instantaneous-power"}, |
4565 | | { 380, "lighting-command"}, |
4566 | | { 381, "lighting-command-default-priority"}, |
4567 | | { 382, "max-actual-value"}, |
4568 | | { 383, "min-actual-value"}, |
4569 | | { 384, "power"}, |
4570 | | { 385, "transition"}, |
4571 | | { 386, "egress-active"}, |
4572 | | { 387, "interface-value"}, |
4573 | | { 388, "fault-high-limit"}, |
4574 | | { 389, "fault-low-limit"}, |
4575 | | { 390, "low-diff-limit"}, |
4576 | | { 391, "strike-count"}, |
4577 | | { 392, "time-of-strike-count-reset"}, |
4578 | | { 393, "default-timeout"}, |
4579 | | { 394, "initial-timeout"}, |
4580 | | { 395, "last-state-change"}, |
4581 | | { 396, "state-change-values"}, |
4582 | | { 397, "timer-running"}, |
4583 | | { 398, "timer-state"}, |
4584 | | { 399, "apdu-length"}, |
4585 | | { 400, "bacnet-ip-address"}, |
4586 | | { 401, "bacnet-ip-default-gateway"}, |
4587 | | { 402, "bacnet-ip-dhcp-enable"}, |
4588 | | { 403, "bacnet-ip-dhcp-lease-time"}, |
4589 | | { 404, "bacnet-ip-dhcp-lease-time-remaining"}, |
4590 | | { 405, "bacnet-ip-dhcp-server"}, |
4591 | | { 406, "bacnet-ip-dns-server"}, |
4592 | | { 407, "bacnet-ip-global-address"}, |
4593 | | { 408, "bacnet-ip-mode"}, |
4594 | | { 409, "bacnet-ip-multicast-address"}, |
4595 | | { 410, "bacnet-ip-nat-traversal"}, |
4596 | | { 411, "bacnet-ip-subnet-mask"}, |
4597 | | { 412, "bacnet-ip-udp-port"}, |
4598 | | { 413, "bbmd-accept-fd-registrations"}, |
4599 | | { 414, "bbmd-broadcast-distribution-table"}, |
4600 | | { 415, "bbmd-foreign-device-table"}, |
4601 | | { 416, "changes-pending"}, |
4602 | | { 417, "command"}, |
4603 | | { 418, "fd-bbmd-address"}, |
4604 | | { 419, "fd-subscription-lifetime"}, |
4605 | | { 420, "link-speed"}, |
4606 | | { 421, "link-speeds"}, |
4607 | | { 422, "link-speed-autonegotiate"}, |
4608 | | { 423, "mac-address"}, |
4609 | | { 424, "network-interface-name"}, |
4610 | | { 425, "network-number"}, |
4611 | | { 426, "network-number-quality"}, |
4612 | | { 427, "network-type"}, |
4613 | | { 428, "routing-table"}, |
4614 | | { 429, "virtual-mac-address-table"}, |
4615 | | { 430, "command-time-array"}, |
4616 | | { 431, "current-command-priority"}, |
4617 | | { 432, "last-command-time"}, |
4618 | | { 433, "value-source"}, |
4619 | | { 434, "value-source-array"}, |
4620 | | { 435, "bacnet-ipv6-mode"}, |
4621 | | { 436, "ipv6-address"}, |
4622 | | { 437, "ipv6-prefix-length"}, |
4623 | | { 438, "bacnet-ipv6-udp-port"}, |
4624 | | { 439, "ipv6-default-gateway"}, |
4625 | | { 440, "bacnet-ipv6-multicast-address"}, |
4626 | | { 441, "ipv6-dns-server"}, |
4627 | | { 442, "ipv6-auto-addressing-enable"}, |
4628 | | { 443, "ipv6-dhcp-lease-time"}, |
4629 | | { 444, "ipv6-dhcp-lease-time-remaining"}, |
4630 | | { 445, "ipv6-dhcp-server"}, |
4631 | | { 446, "ipv6-zone-index"}, |
4632 | | { 447, "assigned-landing-calls"}, |
4633 | | { 448, "car-assigned-direction"}, |
4634 | | { 449, "car-door-command"}, |
4635 | | { 450, "car-door-status"}, |
4636 | | { 451, "car-door-text"}, |
4637 | | { 452, "car-door-zone"}, |
4638 | | { 453, "car-drive-status"}, |
4639 | | { 454, "car-load"}, |
4640 | | { 455, "car-load-units"}, |
4641 | | { 456, "car-mode"}, |
4642 | | { 457, "car-moving-direction"}, |
4643 | | { 458, "car-position"}, |
4644 | | { 459, "elevator-group"}, |
4645 | | { 460, "energy-meter"}, |
4646 | | { 461, "energy-meter-ref"}, |
4647 | | { 462, "escalator-mode"}, |
4648 | | { 463, "fault-signals"}, |
4649 | | { 464, "floor-text"}, |
4650 | | { 465, "group-id"}, |
4651 | | { 466, "enumeration value 466 is unassigned"}, |
4652 | | { 467, "group-mode"}, |
4653 | | { 468, "higher-deck"}, |
4654 | | { 469, "installation-id"}, |
4655 | | { 470, "landing-calls"}, |
4656 | | { 471, "landing-call-control"}, |
4657 | | { 472, "landing-door-status"}, |
4658 | | { 473, "lower-deck"}, |
4659 | | { 474, "machine-room-id"}, |
4660 | | { 475, "making-car-call"}, |
4661 | | { 476, "next-stopping-floor"}, |
4662 | | { 477, "operation-direction"}, |
4663 | | { 478, "passenger-alarm"}, |
4664 | | { 479, "power-mode"}, |
4665 | | { 480, "registered-car-call"}, |
4666 | | { 481, "active-cov-multiple-subscriptions"}, |
4667 | | { 482, "protocol-level"}, |
4668 | | { 483, "reference-port"}, |
4669 | | { 484, "deployed-profile-location"}, |
4670 | | { 485, "profile-location"}, |
4671 | | { 486, "tags"}, |
4672 | | { 487, "subordinate-node-types"}, |
4673 | | { 488, "subordinate-tags"}, |
4674 | | { 489, "subordinate-relationship"}, |
4675 | | { 490, "default-subordinate-relationship"}, |
4676 | | { 491, "represents"}, |
4677 | | { 492, "default-present-value"}, |
4678 | | { 493, "present-stage"}, |
4679 | | { 494, "stages"}, |
4680 | | { 495, "stage-names"}, |
4681 | | { 496, "target-references"}, |
4682 | | { 497, "audit-source-reporter"}, |
4683 | | { 498, "audit-level"}, |
4684 | | { 499, "audit-notification-recipient"}, |
4685 | | { 500, "audit-priority-filter"}, |
4686 | | { 501, "auditable-operations"}, |
4687 | | { 502, "delete-on-forward"}, |
4688 | | { 503, "maximum-send-delay"}, |
4689 | | { 504, "monitored-objects"}, |
4690 | | { 505, "send-now"}, |
4691 | | { 506, "floor-number"}, |
4692 | | { 507, "device-uuid"}, |
4693 | | { 508, "additional-reference-ports"}, |
4694 | | { 509, "certificate-signing-request-file"}, |
4695 | | { 510, "command-validation-result"}, |
4696 | | { 511, "issuer-certificate-files"}, |
4697 | | { 4194304, "max-bvlc-length-accepted"}, |
4698 | | { 4194305, "max-npdu-length-accepted"}, |
4699 | | { 4194306, "operational-certificate-file"}, |
4700 | | { 4194307, "current-health"}, |
4701 | | { 4194308, "sc-connect-wait-timeout"}, |
4702 | | { 4194309, "sc-direct-connect-accept-enable"}, |
4703 | | { 4194310, "sc-direct-connect-accept-uris"}, |
4704 | | { 4194311, "ssc-direct-connect-binding"}, |
4705 | | { 4194312, "sc-direct-connect-connection-status"}, |
4706 | | { 4194313, "sc-direct-connect-initiate-enable"}, |
4707 | | { 4194314, "sc-disconnect-wait-timeout"}, |
4708 | | { 4194315, "sc-failed-connection-request"}, |
4709 | | { 4194316, "sc-failover-hub-connection-status"}, |
4710 | | { 4194317, "sc-failover-hub-uri"}, |
4711 | | { 4194318, "sc-hub-connector-state"}, |
4712 | | { 4194319, "sc-hub-function-accept-uris"}, |
4713 | | { 4194320, "sc-hub-function-binding"}, |
4714 | | { 4194321, "sc-hub-function-connection-status"}, |
4715 | | { 4194322, "sc-hub-function-enable"}, |
4716 | | { 4194323, "sc-heartbeat-timeout"}, |
4717 | | { 4194324, "sc-primary-hub-connection-status"}, |
4718 | | { 4194325, "sc-primary-hub-uri"}, |
4719 | | { 4194326, "sc-maximum-reconnect-time"}, |
4720 | | { 4194327, "sc-minimum-reconnect-time"}, |
4721 | | { 4194328, "color-override"}, |
4722 | | { 4194329, "color-reference"}, |
4723 | | { 4194330, "default-color"}, |
4724 | | { 4194331, "default-color-temperature"}, |
4725 | | { 4194332, "override-color-reference"}, |
4726 | | { 4194334, "color-command"}, |
4727 | | { 4194335, "high_end_trim"}, |
4728 | | { 4194336, "low_end_trim"}, |
4729 | | { 4194337, "trim_fade_time"}, |
4730 | | { 4194338, "device-address-proxy-enable"}, |
4731 | | { 4194339, "device-address-proxy-table"}, |
4732 | | { 4194340, "device-address-proxy-timeout"}, |
4733 | | { 4194341, "default-on-value"}, |
4734 | | { 4194342, "last-on-value"}, |
4735 | | { 4194343, "authorization-cache"}, |
4736 | | { 4194344, "authorization-groups"}, |
4737 | | { 4194345, "authorization-policy"}, |
4738 | | { 4194346, "authorization-scope"}, |
4739 | | { 4194347, "authorization-server"}, |
4740 | | { 4194348, "authorization-status"}, |
4741 | | { 4194349, "max-proxied-i-ams-per-second"}, |
4742 | | { 0, NULL} |
4743 | | /* Enumerated values 0-511 are reserved for definition by ASHRAE. |
4744 | | Enumerated values 512-4194303 may be used by others subject to |
4745 | | the procedures and constraints described in Clause 23. */ |
4746 | | }; |
4747 | | |
4748 | | static const value_string |
4749 | | BACnetBinaryPV [] = { |
4750 | | { 0, "inactive"}, |
4751 | | { 1, "active"}, |
4752 | | { 0, NULL} |
4753 | | }; |
4754 | | |
4755 | | |
4756 | 415 | #define ANSI_X3_4 0 /* ANSI X3.4, a/k/a "ASCII"; full UTF-8 since 2010 */ |
4757 | | /* See, for example, ANSI/ASHRAE Addendum k to ANSI/ASHRAE Standard 135-2008 */ |
4758 | | /* XXX - I've seen captures using this for ISO 8859-1 */ |
4759 | 13.0k | #define IBM_MS_DBCS 1 /* "IBM/Microsoft DBCS"; was there only one such DBCS? */ |
4760 | 125 | #define JIS_C_6226 2 /* JIS C 6226 */ |
4761 | 139 | #define ISO_10646_UCS4 3 /* ISO 10646 (UCS-4) - 4-byte Unicode */ |
4762 | 66 | #define ISO_10646_UCS2 4 /* ISO 10646 (UCS-2) - 2-byte Unicode Basic Multilingual Plane (not UTF-16, presumably) */ |
4763 | 56 | #define ISO_8859_1 5 /* ISO 8859-1 */ |
4764 | | static const value_string |
4765 | | BACnetCharacterSet [] = { |
4766 | | { ANSI_X3_4, "ANSI X3.4 / UTF-8 (since 2010)"}, |
4767 | | { IBM_MS_DBCS, "IBM/Microsoft DBCS"}, |
4768 | | { JIS_C_6226, "JIS C 6226"}, |
4769 | | { ISO_10646_UCS4, "ISO 10646 (UCS-4)"}, |
4770 | | { ISO_10646_UCS2, "ISO 10646 (UCS-2)"}, |
4771 | | { ISO_8859_1, "ISO 8859-1"}, |
4772 | | { 0, NULL} |
4773 | | }; |
4774 | | |
4775 | | static const value_string |
4776 | | BACnetStatusFlags [] = { |
4777 | | { 0, "in-alarm"}, |
4778 | | { 1, "fault"}, |
4779 | | { 2, "overridden"}, |
4780 | | { 3, "out-of-service"}, |
4781 | | { 0, NULL} |
4782 | | }; |
4783 | | |
4784 | | static const value_string |
4785 | | BACnetMessagePriority [] = { |
4786 | | { 0, "normal"}, |
4787 | | { 1, "urgent"}, |
4788 | | { 0, NULL} |
4789 | | }; |
4790 | | |
4791 | | static const value_string |
4792 | | BACnetAcknowledgementFilter [] = { |
4793 | | { 0, "all"}, |
4794 | | { 1, "acked"}, |
4795 | | { 2, "not-acked"}, |
4796 | | { 0, NULL} |
4797 | | }; |
4798 | | |
4799 | | static const value_string |
4800 | | BACnetResultFlags [] = { |
4801 | | { 0, "first-item"}, |
4802 | | { 1, "last-item"}, |
4803 | | { 2, "more-items"}, |
4804 | | { 0, NULL} |
4805 | | }; |
4806 | | |
4807 | | static const value_string |
4808 | | BACnetRelationSpecifier [] = { |
4809 | | { 0, "equal"}, |
4810 | | { 1, "not-equal"}, |
4811 | | { 2, "less-than"}, |
4812 | | { 3, "greater-than"}, |
4813 | | { 4, "less-than-or-equal"}, |
4814 | | { 5, "greater-than-or-equal"}, |
4815 | | { 0, NULL} |
4816 | | }; |
4817 | | |
4818 | | static const value_string |
4819 | | BACnetSelectionLogic [] = { |
4820 | | { 0, "and"}, |
4821 | | { 1, "or"}, |
4822 | | { 2, "all"}, |
4823 | | { 0, NULL} |
4824 | | }; |
4825 | | |
4826 | | static const value_string |
4827 | | BACnetEventStateFilter [] = { |
4828 | | { 0, "offnormal"}, |
4829 | | { 1, "fault"}, |
4830 | | { 2, "normal"}, |
4831 | | { 3, "all"}, |
4832 | | { 4, "active"}, |
4833 | | { 0, NULL} |
4834 | | }; |
4835 | | |
4836 | | static const value_string |
4837 | | BACnetEventTransitionBits [] = { |
4838 | | { 0, "to-offnormal"}, |
4839 | | { 1, "to-fault"}, |
4840 | | { 2, "to-normal"}, |
4841 | | { 0, NULL} |
4842 | | }; |
4843 | | |
4844 | | static const value_string |
4845 | | BACnetSegmentation [] = { |
4846 | | { 0, "segmented-both"}, |
4847 | | { 1, "segmented-transmit"}, |
4848 | | { 2, "segmented-receive"}, |
4849 | | { 3, "no-segmentation"}, |
4850 | | { 0, NULL} |
4851 | | }; |
4852 | | |
4853 | | static const value_string |
4854 | | BACnetSilencedState [] = { |
4855 | | { 0, "unsilenced"}, |
4856 | | { 1, "audible-silenced"}, |
4857 | | { 2, "visible-silenced"}, |
4858 | | { 3, "all-silenced"}, |
4859 | | { 0, NULL} |
4860 | | }; |
4861 | | |
4862 | | static const value_string |
4863 | | BACnetDeviceStatus [] = { |
4864 | | { 0, "operational"}, |
4865 | | { 1, "operational-read-only"}, |
4866 | | { 2, "download-required"}, |
4867 | | { 3, "download-in-progress"}, |
4868 | | { 4, "non-operational"}, |
4869 | | { 5, "backup-in-progress"}, |
4870 | | { 0, NULL} |
4871 | | }; |
4872 | | |
4873 | | static const value_string |
4874 | | BACnetEnableDisable [] = { |
4875 | | { 0, "enable"}, |
4876 | | { 1, "disable"}, |
4877 | | { 2, "disable-initiation"}, |
4878 | | { 0, NULL} |
4879 | | }; |
4880 | | |
4881 | | static const value_string |
4882 | | months [] = { |
4883 | | { 1, "January" }, |
4884 | | { 2, "February" }, |
4885 | | { 3, "March" }, |
4886 | | { 4, "April" }, |
4887 | | { 5, "May" }, |
4888 | | { 6, "June" }, |
4889 | | { 7, "July" }, |
4890 | | { 8, "August" }, |
4891 | | { 9, "September" }, |
4892 | | { 10, "October" }, |
4893 | | { 11, "November" }, |
4894 | | { 12, "December" }, |
4895 | | { 13, "odd month" }, |
4896 | | { 14, "even month" }, |
4897 | | { 255, "any month" }, |
4898 | | { 0, NULL } |
4899 | | }; |
4900 | | |
4901 | | static const value_string |
4902 | | weekofmonth [] = { |
4903 | | { 1, "days numbered 1-7" }, |
4904 | | { 2, "days numbered 8-14" }, |
4905 | | { 3, "days numbered 15-21" }, |
4906 | | { 4, "days numbered 22-28" }, |
4907 | | { 5, "days numbered 29-31" }, |
4908 | | { 6, "last 7 days of this month" }, |
4909 | | { 7, "any of 7 days prior to last 7 days of this month" }, |
4910 | | { 8, "any of 7 days prior to last 14 days of this month" }, |
4911 | | { 9, "any of 7 days prior to last 21 days of this month" }, |
4912 | | { 255, "any week of this month" }, |
4913 | | { 0, NULL } |
4914 | | }; |
4915 | | |
4916 | | /* note: notification class object recipient-list uses |
4917 | | different day-of-week enum */ |
4918 | | static const value_string |
4919 | | day_of_week [] = { |
4920 | | { 1, "Monday" }, |
4921 | | { 2, "Tuesday" }, |
4922 | | { 3, "Wednesday" }, |
4923 | | { 4, "Thursday" }, |
4924 | | { 5, "Friday" }, |
4925 | | { 6, "Saturday" }, |
4926 | | { 7, "Sunday" }, |
4927 | | { 255, "any day of week" }, |
4928 | | { 0, NULL } |
4929 | | }; |
4930 | | |
4931 | | static const value_string |
4932 | | BACnetErrorClass [] = { |
4933 | | { 0, "device" }, |
4934 | | { 1, "object" }, |
4935 | | { 2, "property" }, |
4936 | | { 3, "resources" }, |
4937 | | { 4, "security" }, |
4938 | | { 5, "services" }, |
4939 | | { 6, "vt" }, |
4940 | | { 7, "communication" }, |
4941 | | { 0, NULL } |
4942 | | /* Enumerated values 0-63 are reserved for definition by ASHRAE. |
4943 | | Enumerated values64-65535 may be used by others subject to |
4944 | | the procedures and constraints described in Clause 23. */ |
4945 | | }; |
4946 | | |
4947 | | static const value_string |
4948 | | BACnetVTClass [] = { |
4949 | | { 0, "default-terminal" }, |
4950 | | { 1, "ansi-x3-64" }, |
4951 | | { 2, "dec-vt52" }, |
4952 | | { 3, "dec-vt100" }, |
4953 | | { 4, "dec-vt200" }, |
4954 | | { 5, "hp-700-94" }, |
4955 | | { 6, "ibm-3130" }, |
4956 | | { 0, NULL } |
4957 | | }; |
4958 | | |
4959 | | static const value_string |
4960 | | BACnetEventType [] = { |
4961 | | { 0, "change-of-bitstring" }, |
4962 | | { 1, "change-of-state" }, |
4963 | | { 2, "change-of-value" }, |
4964 | | { 3, "command-failure" }, |
4965 | | { 4, "floating-limit" }, |
4966 | | { 5, "out-of-range" }, |
4967 | | { 6, "complex-event-type" }, |
4968 | | { 7, "(deprecated)event-buffer-ready" }, |
4969 | | { 8, "change-of-life-safety" }, |
4970 | | { 9, "extended" }, |
4971 | | { 10, "buffer-ready" }, |
4972 | | { 11, "unsigned-range" }, |
4973 | | { 13, "access-event" }, |
4974 | | { 14, "double-out-of-range"}, /* added with addenda 135-2008w */ |
4975 | | { 15, "signed-out-of-range"}, |
4976 | | { 16, "unsigned-out-of-range"}, |
4977 | | { 17, "change-of-characterstring"}, |
4978 | | { 18, "change-of-status-flags"}, |
4979 | | { 19, "change-of-reliability" }, |
4980 | | { 20, "none" }, |
4981 | | { 21, "change-of-discrete-value"}, |
4982 | | { 22, "change-of-timer"}, |
4983 | | { 0, NULL } |
4984 | | /* Enumerated values 0-63 are reserved for definition by ASHRAE. |
4985 | | Enumerated values 64-65535 may be used by others subject to |
4986 | | the procedures and constraints described in Clause 23. |
4987 | | It is expected that these enumerated values will correspond |
4988 | | to the use of the complex-event-type CHOICE [6] of the |
4989 | | BACnetNotificationParameters production. */ |
4990 | | }; |
4991 | | |
4992 | | static const value_string |
4993 | | BACnetEventState [] = { |
4994 | | { 0, "normal" }, |
4995 | | { 1, "fault" }, |
4996 | | { 2, "offnormal" }, |
4997 | | { 3, "high-limit" }, |
4998 | | { 4, "low-limit" }, |
4999 | | { 5, "life-safety-alarm" }, |
5000 | | { 0, NULL } |
5001 | | /* Enumerated values 0-63 are reserved for definition by ASHRAE. |
5002 | | Enumerated values 64-65535 may be used by others subject to |
5003 | | the procedures and constraints described in Clause 23. */ |
5004 | | }; |
5005 | | |
5006 | | static const value_string |
5007 | | BACnetLogStatus [] = { |
5008 | | { 0, "log-disabled" }, |
5009 | | { 1, "buffer-purged" }, |
5010 | | { 2, "log-interrupted"}, |
5011 | | { 0, NULL } |
5012 | | }; |
5013 | | |
5014 | | static const value_string |
5015 | | BACnetMaintenance [] = { |
5016 | | { 0, "none" }, |
5017 | | { 1, "periodic-test" }, |
5018 | | { 2, "need-service-operational" }, |
5019 | | { 3, "need-service-inoperative" }, |
5020 | | { 0, NULL } |
5021 | | }; |
5022 | | |
5023 | | static const value_string |
5024 | | BACnetNotifyType [] = { |
5025 | | { 0, "alarm" }, |
5026 | | { 1, "event" }, |
5027 | | { 2, "ack-notification" }, |
5028 | | { 0, NULL } |
5029 | | }; |
5030 | | |
5031 | | static const value_string |
5032 | | BACnetServicesSupported [] = { |
5033 | | { 0, "acknowledgeAlarm"}, |
5034 | | { 1, "confirmedCOVNotification"}, |
5035 | | { 2, "confirmedEventNotification"}, |
5036 | | { 3, "getAlarmSummary"}, |
5037 | | { 4, "getEnrollmentSummary"}, |
5038 | | { 5, "subscribeCOV"}, |
5039 | | { 6, "atomicReadFile"}, |
5040 | | { 7, "atomicWriteFile"}, |
5041 | | { 8, "addListElement"}, |
5042 | | { 9, "removeListElement"}, |
5043 | | { 10, "createObject"}, |
5044 | | { 11, "deleteObject"}, |
5045 | | { 12, "readProperty"}, |
5046 | | { 13, "readPropertyConditional"}, |
5047 | | { 14, "readPropertyMultiple"}, |
5048 | | { 15, "writeProperty"}, |
5049 | | { 16, "writePropertyMultiple"}, |
5050 | | { 17, "deviceCommunicationControl"}, |
5051 | | { 18, "confirmedPrivateTransfer"}, |
5052 | | { 19, "confirmedTextMessage"}, |
5053 | | { 20, "reinitializeDevice"}, |
5054 | | { 21, "vtOpen"}, |
5055 | | { 22, "vtClose"}, |
5056 | | { 23, "vtData"}, |
5057 | | { 24, "authenticate"}, |
5058 | | { 25, "requestKey"}, |
5059 | | { 26, "i-Am"}, |
5060 | | { 27, "i-Have"}, |
5061 | | { 28, "unconfirmedCOVNotification"}, |
5062 | | { 29, "unconfirmedEventNotification"}, |
5063 | | { 30, "unconfirmedPrivateTransfer"}, |
5064 | | { 31, "unconfirmedTextMessage"}, |
5065 | | { 32, "timeSynchronization"}, |
5066 | | { 33, "who-Has"}, |
5067 | | { 34, "who-Is"}, |
5068 | | { 35, "readRange"}, |
5069 | | { 36, "utcTimeSynchronization"}, |
5070 | | { 37, "lifeSafetyOperation"}, |
5071 | | { 38, "subscribeCOVProperty"}, |
5072 | | { 39, "getEventInformation"}, |
5073 | | { 40, "write-group"}, |
5074 | | { 41, "subscribe-cov-property-multiple"}, |
5075 | | { 42, "confirmed-cov-notification-multiple"}, |
5076 | | { 43, "unconfirmed-cov-notification-multiple"}, |
5077 | | { 44, "confirmed-audit-notification"}, |
5078 | | { 45, "audit-log-query"}, |
5079 | | { 46, "unconfirmed-audit-notification"}, |
5080 | | { 47, "who-am-i"}, |
5081 | | { 48, "you-are"}, |
5082 | | { 49, "auth-request"}, |
5083 | | { 0, NULL} |
5084 | | }; |
5085 | | |
5086 | | static const value_string |
5087 | | BACnetPropertyStates [] = { |
5088 | | { 0, "boolean-value"}, |
5089 | | { 1, "binary-value"}, |
5090 | | { 2, "event-type"}, |
5091 | | { 3, "polarity"}, |
5092 | | { 4, "program-change"}, |
5093 | | { 5, "program-state"}, |
5094 | | { 6, "reason-for-halt"}, |
5095 | | { 7, "reliability"}, |
5096 | | { 8, "state"}, |
5097 | | { 9, "system-status"}, |
5098 | | { 10, "units"}, |
5099 | | { 11, "unsigned-value"}, |
5100 | | { 12, "life-safety-mode"}, |
5101 | | { 13, "life-safety-state"}, |
5102 | | { 14, "restart-reason"}, |
5103 | | { 15, "door-alarm-state"}, |
5104 | | { 16, "action"}, |
5105 | | { 17, "door-secured-status"}, |
5106 | | { 18, "door-status"}, |
5107 | | { 19, "door-value"}, |
5108 | | { 20, "file-access-method"}, |
5109 | | { 21, "lock-status"}, |
5110 | | { 22, "life-safety-operation"}, |
5111 | | { 23, "maintenance"}, |
5112 | | { 24, "node-type"}, |
5113 | | { 25, "notify-type"}, |
5114 | | { 26, "security-level"}, |
5115 | | { 27, "shed-state"}, |
5116 | | { 28, "silenced-state"}, |
5117 | | { 29, "unknown-29"}, |
5118 | | { 30, "access-event"}, |
5119 | | { 31, "zone-occupancy-state"}, |
5120 | | { 32, "access-credential-disable-reason"}, |
5121 | | { 33, "access-credential-disable"}, |
5122 | | { 34, "authentication-status"}, |
5123 | | { 35, "unknown-35"}, |
5124 | | { 36, "backup-state"}, |
5125 | | { 37, "write-status"}, |
5126 | | { 38, "lighting-in-progress"}, |
5127 | | { 39, "lighting-operation"}, |
5128 | | { 40, "lighting-transition"}, |
5129 | | { 41, "signed-value"}, |
5130 | | { 42, "unknown-42"}, |
5131 | | { 43, "timer-state"}, |
5132 | | { 44, "timer-transition"}, |
5133 | | { 45, "bacnet-ip-mode"}, |
5134 | | { 46, "network-port-command"}, |
5135 | | { 47, "network-type"}, |
5136 | | { 48, "network-number-quality"}, |
5137 | | { 49, "escalator-operation-direction"}, |
5138 | | { 50, "escalator-fault"}, |
5139 | | { 51, "escalator-mode"}, |
5140 | | { 52, "lift-car-direction"}, |
5141 | | { 53, "lift-car-door-command"}, |
5142 | | { 54, "lift-car-drive-status"}, |
5143 | | { 55, "lift-car-mode"}, |
5144 | | { 56, "lift-group-mode"}, |
5145 | | { 57, "lift-fault"}, |
5146 | | { 58, "protocol-level"}, |
5147 | | { 59, "audit-level"}, |
5148 | | { 60, "audit-operation"}, |
5149 | | { 63, "extended-value"}, |
5150 | | {256, "-- example-one"}, |
5151 | | {257, "-- example-two"}, |
5152 | | {258, "sc-connection-state"}, |
5153 | | {259, "sc-hub-connecto-state"}, |
5154 | | { 0, NULL} |
5155 | | /* Tag values 0-63 are reserved for definition by ASHRAE. |
5156 | | Tag values of 64-254 may be used by others to accommodate |
5157 | | vendor specific properties that have discrete or enumerated values, |
5158 | | subject to the constraints described in Clause 23. */ |
5159 | | }; |
5160 | | |
5161 | | static const value_string |
5162 | | BACnetProgramError [] = { |
5163 | | { 0, "normal"}, |
5164 | | { 1, "load-failed"}, |
5165 | | { 2, "internal"}, |
5166 | | { 3, "program"}, |
5167 | | { 4, "other"}, |
5168 | | { 0, NULL} |
5169 | | /* Enumerated values 0-63 are reserved for definition by ASHRAE. |
5170 | | Enumerated values 64-65535 may be used by others subject to |
5171 | | the procedures and constraints described in Clause 23. */ |
5172 | | }; |
5173 | | |
5174 | | static const value_string |
5175 | | BACnetProgramRequest [] = { |
5176 | | { 0, "ready"}, |
5177 | | { 1, "load"}, |
5178 | | { 2, "run"}, |
5179 | | { 3, "halt"}, |
5180 | | { 4, "restart"}, |
5181 | | { 5, "unload"}, |
5182 | | { 0, NULL} |
5183 | | }; |
5184 | | |
5185 | | static const value_string |
5186 | | BACnetProgramState [] = { |
5187 | | { 0, "idle"}, |
5188 | | { 1, "loading"}, |
5189 | | { 2, "running"}, |
5190 | | { 3, "waiting"}, |
5191 | | { 4, "halted"}, |
5192 | | { 5, "unloading"}, |
5193 | | { 0, NULL} |
5194 | | }; |
5195 | | |
5196 | | static const value_string |
5197 | | BACnetReinitializedStateOfDevice [] = { |
5198 | | { 0, "coldstart"}, |
5199 | | { 1, "warmstart"}, |
5200 | | { 2, "start-backup"}, |
5201 | | { 3, "end-backup"}, |
5202 | | { 4, "start-restore"}, |
5203 | | { 5, "end-restore"}, |
5204 | | { 6, "abort-restore"}, |
5205 | | { 7, "activate-changes"}, |
5206 | | { 0, NULL} |
5207 | | }; |
5208 | | |
5209 | | static const value_string |
5210 | | BACnetPolarity [] = { |
5211 | | { 0, "normal"}, |
5212 | | { 1, "reverse"}, |
5213 | | { 0, NULL} |
5214 | | }; |
5215 | | |
5216 | | static const value_string |
5217 | | BACnetTagNames[] = { |
5218 | | { 5, "Extended Value" }, |
5219 | | { 6, "Opening Tag" }, |
5220 | | { 7, "Closing Tag" }, |
5221 | | { 0, NULL } |
5222 | | }; |
5223 | | |
5224 | | static const value_string |
5225 | | BACnetReadRangeOptions[] = { |
5226 | | { 3, "range byPosition" }, |
5227 | | { 4, "range byTime" }, |
5228 | | { 5, "range timeRange" }, |
5229 | | { 6, "range bySequenceNumber" }, |
5230 | | { 7, "range byTime" }, |
5231 | | { 0, NULL } |
5232 | | }; |
5233 | | |
5234 | | /* Present_Value for Load Control Object */ |
5235 | | static const value_string |
5236 | | BACnetShedState[] = { |
5237 | | { 0, "shed-inactive" }, |
5238 | | { 1, "shed-request-pending" }, |
5239 | | { 2, "shed-compliant" }, |
5240 | | { 3, "shed-non-compliant" }, |
5241 | | { 0, NULL } |
5242 | | }; |
5243 | | |
5244 | | static const value_string |
5245 | | BACnetFaultType[] = { |
5246 | | { 0, "none" }, |
5247 | | { 1, "fault-characterstring" }, |
5248 | | { 2, "fault-extended" }, |
5249 | | { 3, "fault-life-safety" }, |
5250 | | { 4, "fault-state" }, |
5251 | | { 5, "fault-status-flags" }, |
5252 | | { 6, "fault-out-of-range" }, |
5253 | | { 7, "fault-listed" }, |
5254 | | { 0, NULL } |
5255 | | }; |
5256 | | |
5257 | | static const value_string |
5258 | | BACnetNodeType [] = { |
5259 | | { 0, "unknown" }, |
5260 | | { 1, "system" }, |
5261 | | { 2, "network" }, |
5262 | | { 3, "device" }, |
5263 | | { 4, "organizational" }, |
5264 | | { 5, "area" }, |
5265 | | { 6, "equipment" }, |
5266 | | { 7, "point" }, |
5267 | | { 8, "collection" }, |
5268 | | { 9, "property" }, |
5269 | | { 10, "functional" }, |
5270 | | { 11, "other" }, |
5271 | | { 12, "subsystem" }, |
5272 | | { 13, "building" }, |
5273 | | { 14, "floor" }, |
5274 | | { 15, "section" }, |
5275 | | { 16, "module" }, |
5276 | | { 17, "tree" }, |
5277 | | { 18, "member" }, |
5278 | | { 19, "protocol" }, |
5279 | | { 20, "room" }, |
5280 | | { 21, "zone" }, |
5281 | | { 0, NULL } |
5282 | | }; |
5283 | | |
5284 | | static const value_string |
5285 | | BACnetLoggingType [] = { |
5286 | | { 0, "polled" }, |
5287 | | { 1, "cov" }, |
5288 | | { 2, "triggered" }, |
5289 | | { 0, NULL } |
5290 | | }; |
5291 | | |
5292 | | static const value_string |
5293 | | BACnetDoorStatus [] = { |
5294 | | { 0, "closed" }, |
5295 | | { 1, "opened" }, |
5296 | | { 2, "unknown" }, |
5297 | | { 3, "door-fault" }, |
5298 | | { 4, "unused" }, |
5299 | | { 5, "none" }, |
5300 | | { 6, "closing" }, |
5301 | | { 7, "opening" }, |
5302 | | { 8, "safety-locked" }, |
5303 | | { 9, "limited-opened" }, |
5304 | | { 0, NULL } |
5305 | | }; |
5306 | | |
5307 | | static const value_string |
5308 | | BACnetDoorValue[] = { |
5309 | | { 0, "lock" }, |
5310 | | { 1, "unlock" }, |
5311 | | { 2, "pulse-unlock" }, |
5312 | | { 3, "extended-pulse-unlock" }, |
5313 | | { 0, NULL } |
5314 | | }; |
5315 | | |
5316 | | static const value_string |
5317 | | BACnetLockStatus [] = { |
5318 | | { 0, "locked" }, |
5319 | | { 1, "unlocked" }, |
5320 | | { 2, "fault" }, |
5321 | | { 3, "unknown" }, |
5322 | | { 0, NULL } |
5323 | | }; |
5324 | | |
5325 | | static const value_string |
5326 | | BACnetDoorSecuredStatus [] = { |
5327 | | { 0, "secured" }, |
5328 | | { 1, "unsecured" }, |
5329 | | { 2, "unknown" }, |
5330 | | { 0, NULL } |
5331 | | }; |
5332 | | |
5333 | | static const value_string |
5334 | | BACnetDoorAlarmState [] = { |
5335 | | { 0, "normal" }, |
5336 | | { 1, "alarm" }, |
5337 | | { 2, "door-open-too-long" }, |
5338 | | { 3, "forced-open" }, |
5339 | | { 4, "tamper" }, |
5340 | | { 5, "door-fault" }, |
5341 | | { 6, "lock-down" }, |
5342 | | { 7, "free-access" }, |
5343 | | { 8, "egress-open" }, |
5344 | | { 0, NULL } |
5345 | | }; |
5346 | | |
5347 | | static const value_string |
5348 | | BACnetSecurityPolicy [] = { |
5349 | | { 0, "plain-non-trusted"}, |
5350 | | { 1, "plain-trusted"}, |
5351 | | { 2, "signed-trusted"}, |
5352 | | { 3, "encrypted-trusted"}, |
5353 | | { 0, NULL } |
5354 | | }; |
5355 | | |
5356 | | static const value_string |
5357 | | BACnetAccumulatorStatus [] = { |
5358 | | { 0, "normal" }, |
5359 | | { 1, "starting" }, |
5360 | | { 2, "recovered" }, |
5361 | | { 3, "abnormal" }, |
5362 | | { 4, "failed" }, |
5363 | | { 0, NULL } |
5364 | | }; |
5365 | | |
5366 | | static const value_string |
5367 | | BACnetAuditLevel [] = { |
5368 | | { 0, "none" }, |
5369 | | { 1, "audit-all" }, |
5370 | | { 2, "audit-config" }, |
5371 | | { 3, "default" }, |
5372 | | { 0, NULL } |
5373 | | }; |
5374 | | |
5375 | | static const value_string |
5376 | | BACnetAuditPriorityFilter [] = { |
5377 | | { 1, "manual-life-safety" }, |
5378 | | { 2, "automatic-life-safety" }, |
5379 | | { 3, "priority-3" }, |
5380 | | { 4, "priority-4" }, |
5381 | | { 5, "critical-equipment-controls" }, |
5382 | | { 6, "minimum-on-off" }, |
5383 | | { 7, "priority-7" }, |
5384 | | { 8, "manual-operator" }, |
5385 | | { 9, "priority-9" }, |
5386 | | { 10, "priority-10" }, |
5387 | | { 11, "priority-11" }, |
5388 | | { 12, "priority-12" }, |
5389 | | { 13, "priority-13" }, |
5390 | | { 14, "priority-14" }, |
5391 | | { 15, "priority-15" }, |
5392 | | { 16, "priority-16" }, |
5393 | | { 0, NULL } |
5394 | | }; |
5395 | | |
5396 | | static const value_string |
5397 | | BACnetAuditOperation [] = { |
5398 | | { 0, "read" }, |
5399 | | { 1, "write" }, |
5400 | | { 2, "create" }, |
5401 | | { 3, "delete" }, |
5402 | | { 4, "life-safety" }, |
5403 | | { 5, "acknowledge-alarm" }, |
5404 | | { 6, "device-disable-comm" }, |
5405 | | { 7, "device-enable-comm" }, |
5406 | | { 8, "device-reset" }, |
5407 | | { 9, "device-backup" }, |
5408 | | { 10, "device-restore" }, |
5409 | | { 11, "subscription" }, |
5410 | | { 12, "notification" }, |
5411 | | { 13, "auditing-failure" }, |
5412 | | { 14, "network-changes" }, |
5413 | | { 15, "general" }, |
5414 | | { 0, NULL } |
5415 | | }; |
5416 | | |
5417 | | static const value_string |
5418 | | BACnetSuccessFilter [] = { |
5419 | | { 0, "all" }, |
5420 | | { 1, "successes-only" }, |
5421 | | { 2, "failures-only" }, |
5422 | | { 0, NULL } |
5423 | | }; |
5424 | | |
5425 | | static const value_string |
5426 | | BACnetAuthorizationScopeStandard [] = { |
5427 | | { 0, "view" }, |
5428 | | { 1, "adjust" }, |
5429 | | { 2, "control" }, |
5430 | | { 3, "override" }, |
5431 | | { 4, "config" }, |
5432 | | { 5, "bind" }, |
5433 | | { 6, "install" }, |
5434 | | { 7, "auth" }, |
5435 | | { 8, "infrastructure" }, |
5436 | | { 9, "reserved-9" }, |
5437 | | { 10, "reserved-10" }, |
5438 | | { 11, "reserved-11" }, |
5439 | | { 12, "reserved-12" }, |
5440 | | { 13, "reserved-13" }, |
5441 | | { 14, "reserved-14" }, |
5442 | | { 15, "reserved-15" }, |
5443 | | { 16, "reserved-16" }, |
5444 | | { 17, "reserved-17" }, |
5445 | | { 18, "reserved-18" }, |
5446 | | { 19, "reserved-19" }, |
5447 | | { 20, "reserved-20" }, |
5448 | | { 21, "reserved-21" }, |
5449 | | { 22, "reserved-22" }, |
5450 | | { 23, "reserved-23" }, |
5451 | | { 0, NULL } |
5452 | | }; |
5453 | | |
5454 | | static const value_string |
5455 | | BACnetAuthorizationPosture[] = { |
5456 | | { 0, "open" }, |
5457 | | { 1, "proprietary" }, |
5458 | | { 2, "configured" }, |
5459 | | { 3, "misconfigured-partial" }, |
5460 | | { 4, "misconfigured-total" }, |
5461 | | { 0, NULL } |
5462 | | }; |
5463 | | |
5464 | | static const value_string |
5465 | | BACnetAuthenticationDecision[] = { |
5466 | | { 0, "allow-match" }, |
5467 | | { 1, "deny-mismatch" }, |
5468 | | { 2, "deny-non-relay" }, |
5469 | | { 0, NULL } |
5470 | | }; |
5471 | | |
5472 | | static const value_string |
5473 | | BACnetAuthorizationDecision[] = { |
5474 | | { 0, "allow-by-token" }, |
5475 | | { 1, "allow-by-local-polic" }, |
5476 | | { 2, "deny-no-token-or-policy" }, |
5477 | | { 3, "deny-not-before" }, |
5478 | | { 4, "deny-not-after" }, |
5479 | | { 5, "deny-target-device" }, |
5480 | | { 6, "deny-target-group" }, |
5481 | | { 7, "deny-client-device" }, |
5482 | | { 8, "deny-client-method" }, |
5483 | | { 9, "deny-scope" }, |
5484 | | { 10, "deny-issuer" }, |
5485 | | { 11, "deny-revoked" }, |
5486 | | { 12, "deny-signature" }, |
5487 | | { 13, "deny-other" }, |
5488 | | { 0, NULL } |
5489 | | }; |
5490 | | |
5491 | | static const value_string |
5492 | | BACnetAuthorizationConstraintOrigin[] = { |
5493 | | { 0, "direct-connect" }, |
5494 | | { 1, "same-network" }, |
5495 | | { 2, "any-network" }, |
5496 | | { 0, NULL } |
5497 | | }; |
5498 | | |
5499 | | static const value_string |
5500 | | BACnetAuthorizationConstraintAuthentication[] = { |
5501 | | { 0, "certified" }, |
5502 | | { 1, "secure-path" }, |
5503 | | { 2, "any-method" }, |
5504 | | { 0, NULL } |
5505 | | }; |
5506 | | |
5507 | | extern value_string_ext BACnetVendorIdentifiers_ext; |
5508 | | |
5509 | | static int proto_bacapp; |
5510 | | static int hf_bacapp_type; |
5511 | | static int hf_bacapp_pduflags; |
5512 | | static int hf_bacapp_SEG; |
5513 | | static int hf_bacapp_MOR; |
5514 | | static int hf_bacapp_SA; |
5515 | | static int hf_bacapp_response_segments; |
5516 | | static int hf_bacapp_max_adpu_size; |
5517 | | static int hf_bacapp_invoke_id; |
5518 | | static int hf_bacapp_object_identifier; |
5519 | | static int hf_bacapp_device_identifier; |
5520 | | static int hf_bacapp_objectType; |
5521 | | static int hf_bacapp_object_name; |
5522 | | static int hf_bacapp_instanceNumber; |
5523 | | static int hf_bacapp_sequence_number; |
5524 | | static int hf_bacapp_window_size; |
5525 | | static int hf_bacapp_service; |
5526 | | static int hf_bacapp_NAK; |
5527 | | static int hf_bacapp_SRV; |
5528 | | static int hf_bacapp_notify_type; |
5529 | | static int hf_bacapp_event_type; |
5530 | | static int hf_bacapp_error_class; |
5531 | | static int hf_bacapp_error_code; |
5532 | | static int hf_Device_Instance_Range_Low_Limit; |
5533 | | static int hf_Device_Instance_Range_High_Limit; |
5534 | | static int hf_BACnetRejectReason; |
5535 | | static int hf_BACnetAbortReason; |
5536 | | static int hf_BACnetApplicationTagNumber; |
5537 | | static int hf_BACnetContextTagNumber; |
5538 | | static int hf_BACnetExtendedTagNumber; |
5539 | | static int hf_BACnetNamedTag; |
5540 | | static int hf_BACnetTagClass; |
5541 | | static int hf_BACnetCharacterSet; |
5542 | | static int hf_BACnetCodePage; |
5543 | | static int hf_bacapp_tag_lvt; |
5544 | | static int hf_bacapp_tag_ProcessId; |
5545 | | static int hf_bacapp_tag_to_state; |
5546 | | static int hf_bacapp_tag_from_state; |
5547 | | static int hf_bacapp_uservice; |
5548 | | static int hf_BACnetPropertyIdentifier; |
5549 | | static int hf_BACnetVendorIdentifier; |
5550 | | static int hf_BACnetRestartReason; |
5551 | | static int hf_bacapp_tag_IPV4; |
5552 | | static int hf_bacapp_tag_IPV6; |
5553 | | static int hf_bacapp_tag_PORT; |
5554 | | static int hf_bacapp_tag_mac_address_broadcast; |
5555 | | static int hf_bacapp_reserved_ashrea; |
5556 | | static int hf_bacapp_unused_bits; |
5557 | | static int hf_bacapp_bit; |
5558 | | static int hf_bacapp_complete_bitstring; |
5559 | | |
5560 | | /* present value */ |
5561 | | static int hf_bacapp_present_value_null; |
5562 | | static int hf_bacapp_present_value_bool; |
5563 | | static int hf_bacapp_present_value_unsigned; |
5564 | | static int hf_bacapp_present_value_signed; |
5565 | | static int hf_bacapp_present_value_real; |
5566 | | static int hf_bacapp_present_value_double; |
5567 | | static int hf_bacapp_present_value_octet_string; |
5568 | | static int hf_bacapp_present_value_char_string; |
5569 | | static int hf_bacapp_present_value_bit_string; |
5570 | | static int hf_bacapp_present_value_enum_index; |
5571 | | |
5572 | | /* some more variables for segmented messages */ |
5573 | | static int hf_msg_fragments; |
5574 | | static int hf_msg_fragment; |
5575 | | static int hf_msg_fragment_overlap; |
5576 | | static int hf_msg_fragment_overlap_conflicts; |
5577 | | static int hf_msg_fragment_multiple_tails; |
5578 | | static int hf_msg_fragment_too_long_fragment; |
5579 | | static int hf_msg_fragment_error; |
5580 | | static int hf_msg_fragment_count; |
5581 | | static int hf_msg_reassembled_in; |
5582 | | static int hf_msg_reassembled_length; |
5583 | | |
5584 | | static int ett_msg_fragment; |
5585 | | static int ett_msg_fragments; |
5586 | | |
5587 | | static int ett_bacapp; |
5588 | | static int ett_bacapp_control; |
5589 | | static int ett_bacapp_tag; |
5590 | | static int ett_bacapp_list; |
5591 | | static int ett_bacapp_value; |
5592 | | static int ett_bacapp_object_identifier; |
5593 | | |
5594 | | static expert_field ei_bacapp_bad_length; |
5595 | | static expert_field ei_bacapp_bad_tag; |
5596 | | static expert_field ei_bacapp_opening_tag; |
5597 | | |
5598 | | static int32_t propertyIdentifier = -1; |
5599 | | static int32_t propertyArrayIndex = -1; |
5600 | | static uint32_t object_type = 4096; |
5601 | | |
5602 | | static uint8_t bacapp_flags; |
5603 | | static uint8_t bacapp_seq; |
5604 | | |
5605 | | /* Defined to allow vendor identifier registration of private transfer dissectors */ |
5606 | | static dissector_table_t bacapp_dissector_table; |
5607 | | |
5608 | | |
5609 | | /* Stat: BACnet Packets sorted by IP */ |
5610 | | bacapp_info_value_t bacinfo; |
5611 | | |
5612 | | static const char* st_str_packets_by_ip = "BACnet Packets by IP"; |
5613 | | static const char* st_str_packets_by_ip_dst = "By Destination"; |
5614 | | static const char* st_str_packets_by_ip_src = "By Source"; |
5615 | | static int st_node_packets_by_ip = -1; |
5616 | | static int st_node_packets_by_ip_dst = -1; |
5617 | | static int st_node_packets_by_ip_src = -1; |
5618 | | |
5619 | | static void |
5620 | | bacapp_packet_stats_tree_init(stats_tree* st) |
5621 | 0 | { |
5622 | 0 | st_node_packets_by_ip = stats_tree_create_pivot(st, st_str_packets_by_ip, 0); |
5623 | 0 | st_node_packets_by_ip_src = stats_tree_create_node(st, st_str_packets_by_ip_src, st_node_packets_by_ip, STAT_DT_INT, true); |
5624 | 0 | st_node_packets_by_ip_dst = stats_tree_create_node(st, st_str_packets_by_ip_dst, st_node_packets_by_ip, STAT_DT_INT, true); |
5625 | 0 | } |
5626 | | |
5627 | | static char * |
5628 | | bacapp_get_address_label(const char *tag, address *addr) |
5629 | 0 | { |
5630 | 0 | char *addr_str, *label_str; |
5631 | |
|
5632 | 0 | addr_str = address_to_str(NULL, addr); |
5633 | 0 | label_str = wmem_strconcat(NULL, tag, addr_str, NULL); |
5634 | 0 | wmem_free(NULL, addr_str); |
5635 | 0 | return label_str; |
5636 | 0 | } |
5637 | | |
5638 | | static tap_packet_status |
5639 | | bacapp_stats_tree_packet(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p, tap_flags_t flags _U_) |
5640 | 0 | { |
5641 | 0 | int packets_for_this_dst; |
5642 | 0 | int packets_for_this_src; |
5643 | 0 | int service_for_this_dst; |
5644 | 0 | int service_for_this_src; |
5645 | 0 | int src_for_this_dst; |
5646 | 0 | int dst_for_this_src; |
5647 | 0 | int objectid_for_this_dst; |
5648 | 0 | int objectid_for_this_src; |
5649 | 0 | int instanceid_for_this_dst; |
5650 | 0 | int instanceid_for_this_src; |
5651 | 0 | char *dststr; |
5652 | 0 | char *srcstr; |
5653 | 0 | const bacapp_info_value_t *binfo = (const bacapp_info_value_t *)p; |
5654 | |
|
5655 | 0 | srcstr = bacapp_get_address_label("Src: ", &pinfo->src); |
5656 | 0 | dststr = bacapp_get_address_label("Dst: ", &pinfo->dst); |
5657 | |
|
5658 | 0 | tick_stat_node(st, st_str_packets_by_ip, 0, true); |
5659 | 0 | packets_for_this_dst = tick_stat_node(st, st_str_packets_by_ip_dst, st_node_packets_by_ip, true); |
5660 | 0 | packets_for_this_src = tick_stat_node(st, st_str_packets_by_ip_src, st_node_packets_by_ip, true); |
5661 | 0 | src_for_this_dst = tick_stat_node(st, dststr, packets_for_this_dst, true); |
5662 | 0 | dst_for_this_src = tick_stat_node(st, srcstr, packets_for_this_src, true); |
5663 | 0 | service_for_this_src = tick_stat_node(st, dststr, dst_for_this_src, true); |
5664 | 0 | service_for_this_dst = tick_stat_node(st, srcstr, src_for_this_dst, true); |
5665 | 0 | if (binfo->service_type) { |
5666 | 0 | objectid_for_this_dst = tick_stat_node(st, binfo->service_type, service_for_this_dst, true); |
5667 | 0 | objectid_for_this_src = tick_stat_node(st, binfo->service_type, service_for_this_src, true); |
5668 | 0 | if (binfo->object_ident) { |
5669 | 0 | instanceid_for_this_dst = tick_stat_node(st, binfo->object_ident, objectid_for_this_dst, true); |
5670 | 0 | tick_stat_node(st, binfo->instance_ident, instanceid_for_this_dst, false); |
5671 | 0 | instanceid_for_this_src = tick_stat_node(st, binfo->object_ident, objectid_for_this_src, true); |
5672 | 0 | tick_stat_node(st, binfo->instance_ident, instanceid_for_this_src, false); |
5673 | 0 | } |
5674 | 0 | } |
5675 | |
|
5676 | 0 | wmem_free(NULL, srcstr); |
5677 | 0 | wmem_free(NULL, dststr); |
5678 | |
|
5679 | 0 | return TAP_PACKET_REDRAW; |
5680 | 0 | } |
5681 | | |
5682 | | /* Stat: BACnet Packets sorted by Service */ |
5683 | | static const char* st_str_packets_by_service = "BACnet Packets by Service"; |
5684 | | static int st_node_packets_by_service = -1; |
5685 | | |
5686 | | static void |
5687 | | bacapp_service_stats_tree_init(stats_tree* st) |
5688 | 0 | { |
5689 | 0 | st_node_packets_by_service = stats_tree_create_pivot(st, st_str_packets_by_service, 0); |
5690 | 0 | } |
5691 | | |
5692 | | static tap_packet_status |
5693 | | bacapp_stats_tree_service(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p, tap_flags_t flags _U_) |
5694 | 0 | { |
5695 | 0 | int servicetype; |
5696 | 0 | int src, dst; |
5697 | 0 | int objectid; |
5698 | |
|
5699 | 0 | char *dststr; |
5700 | 0 | char *srcstr; |
5701 | |
|
5702 | 0 | const bacapp_info_value_t *binfo = (const bacapp_info_value_t *)p; |
5703 | |
|
5704 | 0 | srcstr = bacapp_get_address_label("Src: ", &pinfo->src); |
5705 | 0 | dststr = bacapp_get_address_label("Dst: ", &pinfo->dst); |
5706 | |
|
5707 | 0 | tick_stat_node(st, st_str_packets_by_service, 0, true); |
5708 | 0 | if (binfo->service_type) { |
5709 | 0 | servicetype = tick_stat_node(st, binfo->service_type, st_node_packets_by_service, true); |
5710 | 0 | src = tick_stat_node(st, srcstr, servicetype, true); |
5711 | 0 | dst = tick_stat_node(st, dststr, src, true); |
5712 | 0 | if (binfo->object_ident) { |
5713 | 0 | objectid = tick_stat_node(st, binfo->object_ident, dst, true); |
5714 | 0 | tick_stat_node(st, binfo->instance_ident, objectid, false); |
5715 | 0 | } |
5716 | 0 | } |
5717 | |
|
5718 | 0 | wmem_free(NULL, srcstr); |
5719 | 0 | wmem_free(NULL, dststr); |
5720 | |
|
5721 | 0 | return TAP_PACKET_REDRAW; |
5722 | 0 | } |
5723 | | |
5724 | | /* Stat: BACnet Packets sorted by Object Type */ |
5725 | | static const char* st_str_packets_by_objectid = "BACnet Packets by Object Type"; |
5726 | | static int st_node_packets_by_objectid = -1; |
5727 | | |
5728 | | static void |
5729 | | bacapp_objectid_stats_tree_init(stats_tree* st) |
5730 | 0 | { |
5731 | 0 | st_node_packets_by_objectid = stats_tree_create_pivot(st, st_str_packets_by_objectid, 0); |
5732 | 0 | } |
5733 | | |
5734 | | static tap_packet_status |
5735 | | bacapp_stats_tree_objectid(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p, tap_flags_t flags _U_) |
5736 | 0 | { |
5737 | 0 | int servicetype; |
5738 | 0 | int src, dst; |
5739 | 0 | int objectid; |
5740 | |
|
5741 | 0 | char *dststr; |
5742 | 0 | char *srcstr; |
5743 | 0 | const bacapp_info_value_t *binfo = (const bacapp_info_value_t *)p; |
5744 | |
|
5745 | 0 | srcstr = bacapp_get_address_label("Src: ", &pinfo->src); |
5746 | 0 | dststr = bacapp_get_address_label("Dst: ", &pinfo->dst); |
5747 | |
|
5748 | 0 | tick_stat_node(st, st_str_packets_by_objectid, 0, true); |
5749 | 0 | if (binfo->object_ident) { |
5750 | 0 | objectid = tick_stat_node(st, binfo->object_ident, st_node_packets_by_objectid, true); |
5751 | 0 | src = tick_stat_node(st, srcstr, objectid, true); |
5752 | 0 | dst = tick_stat_node(st, dststr, src, true); |
5753 | 0 | if (binfo->service_type) { |
5754 | 0 | servicetype = tick_stat_node(st, binfo->service_type, dst, true); |
5755 | 0 | tick_stat_node(st, binfo->instance_ident, servicetype, false); |
5756 | 0 | } |
5757 | 0 | } |
5758 | |
|
5759 | 0 | wmem_free(NULL, srcstr); |
5760 | 0 | wmem_free(NULL, dststr); |
5761 | |
|
5762 | 0 | return TAP_PACKET_REDRAW; |
5763 | 0 | } |
5764 | | |
5765 | | /* Stat: BACnet Packets sorted by Instance No */ |
5766 | | static const char* st_str_packets_by_instanceid = "BACnet Packets by Instance ID"; |
5767 | | static int st_node_packets_by_instanceid = -1; |
5768 | | |
5769 | | static void |
5770 | | bacapp_instanceid_stats_tree_init(stats_tree* st) |
5771 | 0 | { |
5772 | 0 | st_node_packets_by_instanceid = stats_tree_create_pivot(st, st_str_packets_by_instanceid, 0); |
5773 | 0 | } |
5774 | | |
5775 | | static tap_packet_status |
5776 | | bacapp_stats_tree_instanceid(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p, tap_flags_t flags _U_) |
5777 | 0 | { |
5778 | 0 | int servicetype; |
5779 | 0 | int src, dst; |
5780 | 0 | int instanceid; |
5781 | |
|
5782 | 0 | char *dststr; |
5783 | 0 | char *srcstr; |
5784 | 0 | const bacapp_info_value_t *binfo = (const bacapp_info_value_t *)p; |
5785 | |
|
5786 | 0 | srcstr = bacapp_get_address_label("Src: ", &pinfo->src); |
5787 | 0 | dststr = bacapp_get_address_label("Dst: ", &pinfo->dst); |
5788 | |
|
5789 | 0 | tick_stat_node(st, st_str_packets_by_instanceid, 0, true); |
5790 | 0 | if (binfo->object_ident) { |
5791 | 0 | instanceid = tick_stat_node(st, binfo->instance_ident, st_node_packets_by_instanceid, true); |
5792 | 0 | src = tick_stat_node(st, srcstr, instanceid, true); |
5793 | 0 | dst = tick_stat_node(st, dststr, src, true); |
5794 | 0 | if (binfo->service_type) { |
5795 | 0 | servicetype = tick_stat_node(st, binfo->service_type, dst, true); |
5796 | 0 | tick_stat_node(st, binfo->object_ident, servicetype, false); |
5797 | 0 | } |
5798 | 0 | } |
5799 | |
|
5800 | 0 | wmem_free(NULL, srcstr); |
5801 | 0 | wmem_free(NULL, dststr); |
5802 | |
|
5803 | 0 | return TAP_PACKET_REDRAW; |
5804 | 0 | } |
5805 | | |
5806 | | |
5807 | | /* register all BACnet Statistic trees */ |
5808 | | static void |
5809 | | register_bacapp_stat_trees(void) |
5810 | 14 | { |
5811 | 14 | stats_tree_register("bacapp", "bacapp_ip", "BACnet" STATS_TREE_MENU_SEPARATOR "Packets sorted by IP", 0, |
5812 | 14 | bacapp_stats_tree_packet, bacapp_packet_stats_tree_init, NULL); |
5813 | 14 | stats_tree_register("bacapp", "bacapp_service", "BACnet" STATS_TREE_MENU_SEPARATOR "Packets sorted by Service", 0, |
5814 | 14 | bacapp_stats_tree_service, bacapp_service_stats_tree_init, NULL); |
5815 | 14 | stats_tree_register("bacapp", "bacapp_objectid", "BACnet" STATS_TREE_MENU_SEPARATOR "Packets sorted by Object Type", 0, |
5816 | 14 | bacapp_stats_tree_objectid, bacapp_objectid_stats_tree_init, NULL); |
5817 | 14 | stats_tree_register("bacapp", "bacapp_instanceid", "BACnet" STATS_TREE_MENU_SEPARATOR "Packets sorted by Instance ID", 0, |
5818 | 14 | bacapp_stats_tree_instanceid, bacapp_instanceid_stats_tree_init, NULL); |
5819 | 14 | } |
5820 | | |
5821 | | /* 'data' must be allocated with wmem packet scope */ |
5822 | | static int |
5823 | | updateBacnetInfoValue(int whichval, const char *data) |
5824 | 80.9k | { |
5825 | 80.9k | if (whichval == BACINFO_SERVICE) { |
5826 | 9.08k | bacinfo.service_type = data; |
5827 | 9.08k | return 0; |
5828 | 9.08k | } |
5829 | 71.8k | if (whichval == BACINFO_INVOKEID) { |
5830 | 8.42k | bacinfo.invoke_id = data; |
5831 | 8.42k | return 0; |
5832 | 8.42k | } |
5833 | 63.4k | if (whichval == BACINFO_OBJECTID) { |
5834 | 31.7k | bacinfo.object_ident = data; |
5835 | 31.7k | return 0; |
5836 | 31.7k | } |
5837 | 31.7k | if (whichval == BACINFO_INSTANCEID) { |
5838 | 31.7k | bacinfo.instance_ident = data; |
5839 | 31.7k | return 0; |
5840 | 31.7k | } |
5841 | 0 | return -1; |
5842 | 31.7k | } |
5843 | | |
5844 | | static const fragment_items msg_frag_items = { |
5845 | | /* Fragment subtrees */ |
5846 | | &ett_msg_fragment, |
5847 | | &ett_msg_fragments, |
5848 | | /* Fragment fields */ |
5849 | | &hf_msg_fragments, |
5850 | | &hf_msg_fragment, |
5851 | | &hf_msg_fragment_overlap, |
5852 | | &hf_msg_fragment_overlap_conflicts, |
5853 | | &hf_msg_fragment_multiple_tails, |
5854 | | &hf_msg_fragment_too_long_fragment, |
5855 | | &hf_msg_fragment_error, |
5856 | | &hf_msg_fragment_count, |
5857 | | /* Reassembled in field */ |
5858 | | &hf_msg_reassembled_in, |
5859 | | /* Reassembled length field */ |
5860 | | &hf_msg_reassembled_length, |
5861 | | /* Reassembled data field */ |
5862 | | NULL, |
5863 | | /* Tag */ |
5864 | | "Message fragments" |
5865 | | }; |
5866 | | |
5867 | | /* calculate an extended sequence number. The sequence number is an 8-bit |
5868 | | * counter, and can rollover with very large data length. */ |
5869 | | static uint32_t |
5870 | | calculate_extended_seqno(uint32_t prev_seqno, uint8_t raw_seqno) |
5871 | 47 | { |
5872 | 47 | uint32_t seqno = (prev_seqno & 0xffffff00) | raw_seqno; |
5873 | | /* The Window Size must be in a range 1 to 127 (see ANSI/ASHRAE Std |
5874 | | * 135-2016 5.3), and this guarantees that, e.g., sequence number 128 |
5875 | | * will not be transmitted unless a SegmentACK has been received for |
5876 | | * sequence number 0, so any subsequent sequence number 0 must actually |
5877 | | * be sequence number 256 after rollover. |
5878 | | */ |
5879 | 47 | if (seqno + 0x80 < prev_seqno) { |
5880 | 0 | seqno += 0x100; |
5881 | 47 | } else if (prev_seqno + 0x80 < seqno) { |
5882 | | /* Unlikely, out-of-order packet backwards over the wrap boundary. */ |
5883 | 14 | seqno -= 0x100; |
5884 | 14 | } |
5885 | 47 | return seqno; |
5886 | 47 | } |
5887 | | |
5888 | | #if 0 |
5889 | | /* if BACnet uses the reserved values, then patch the corresponding values here, maximum 16 values are defined */ |
5890 | | /* FIXME: fGetMaxAPDUSize is commented out, as it is not used. It was used to set variables which were not later used. */ |
5891 | | static const unsigned MaxAPDUSize [] = { 50, 128, 206, 480, 1024, 1476 }; |
5892 | | |
5893 | | static unsigned |
5894 | | fGetMaxAPDUSize(uint8_t idx) |
5895 | | { |
5896 | | /* only 16 values are defined, so use & 0x0f */ |
5897 | | /* check the size of the Array, deliver either the entry |
5898 | | or the first entry if idx is outside of the array (bug 3736 comment#7) */ |
5899 | | |
5900 | | if ((idx & 0x0f) >= (int)array_length(MaxAPDUSize)) |
5901 | | return MaxAPDUSize[0]; |
5902 | | else |
5903 | | return MaxAPDUSize[idx & 0x0f]; |
5904 | | } |
5905 | | #endif |
5906 | | |
5907 | | /* Used when there are ranges of reserved and proprietary enumerations */ |
5908 | | static const char* |
5909 | | val_to_split_str(wmem_allocator_t* scope, uint32_t val, uint32_t split_val, const value_string *vs, |
5910 | | const char *fmt, const char *split_fmt) |
5911 | 134k | { |
5912 | 134k | if (val < split_val) |
5913 | 93.5k | return val_to_str(scope, val, vs, fmt); |
5914 | 41.4k | else |
5915 | 41.4k | return val_to_str(scope, val, vs, split_fmt); |
5916 | 134k | } |
5917 | | |
5918 | | /* from clause 20.2.1.3.2 Constructed Data */ |
5919 | | /* returns true if the extended value is used */ |
5920 | | static bool |
5921 | | tag_is_extended_value(uint8_t tag) |
5922 | 1.92M | { |
5923 | 1.92M | return (tag & 0x07) == 5; |
5924 | 1.92M | } |
5925 | | |
5926 | | static bool |
5927 | | tag_is_opening(uint8_t tag) |
5928 | 1.14M | { |
5929 | 1.14M | return (tag & 0x07) == 6; |
5930 | 1.14M | } |
5931 | | |
5932 | | static bool |
5933 | | tag_is_closing(uint8_t tag) |
5934 | 1.48M | { |
5935 | 1.48M | return (tag & 0x07) == 7; |
5936 | 1.48M | } |
5937 | | |
5938 | | /* from clause 20.2.1.1 Class |
5939 | | class bit shall be one for context specific tags */ |
5940 | | /* returns true if the tag is context specific */ |
5941 | | static bool |
5942 | | tag_is_context_specific(uint8_t tag) |
5943 | 2.54M | { |
5944 | 2.54M | return (tag & 0x08) != 0; |
5945 | 2.54M | } |
5946 | | |
5947 | | static bool |
5948 | | tag_is_extended_tag_number(uint8_t tag) |
5949 | 2.00M | { |
5950 | 2.00M | return ((tag & 0xF0) == 0xF0); |
5951 | 2.00M | } |
5952 | | |
5953 | | static uint32_t |
5954 | | object_id_type(uint32_t object_identifier) |
5955 | 32.3k | { |
5956 | 32.3k | return ((object_identifier >> 22) & 0x3FF); |
5957 | 32.3k | } |
5958 | | |
5959 | | static uint32_t |
5960 | | object_id_instance(uint32_t object_identifier) |
5961 | 95.1k | { |
5962 | 95.1k | return (object_identifier & 0x3FFFFF); |
5963 | 95.1k | } |
5964 | | |
5965 | | static unsigned |
5966 | | fTagNo(tvbuff_t *tvb, unsigned offset) |
5967 | 108k | { |
5968 | 108k | return (unsigned)(tvb_get_uint8(tvb, offset) >> 4); |
5969 | 108k | } |
5970 | | |
5971 | | static bool |
5972 | | fUnsigned32(tvbuff_t *tvb, unsigned offset, uint32_t lvt, uint32_t *val) |
5973 | 140k | { |
5974 | 140k | bool valid = true; |
5975 | | |
5976 | 140k | switch (lvt) { |
5977 | 20.0k | case 1: |
5978 | 20.0k | *val = tvb_get_uint8(tvb, offset); |
5979 | 20.0k | break; |
5980 | 12.3k | case 2: |
5981 | 12.3k | *val = tvb_get_ntohs(tvb, offset); |
5982 | 12.3k | break; |
5983 | 6.62k | case 3: |
5984 | 6.62k | *val = tvb_get_ntoh24(tvb, offset); |
5985 | 6.62k | break; |
5986 | 8.01k | case 4: |
5987 | 8.01k | *val = tvb_get_ntohl(tvb, offset); |
5988 | 8.01k | break; |
5989 | 93.8k | default: |
5990 | 93.8k | valid = false; |
5991 | 93.8k | break; |
5992 | 140k | } |
5993 | | |
5994 | 140k | return valid; |
5995 | 140k | } |
5996 | | |
5997 | | static bool |
5998 | | fUnsigned64(tvbuff_t *tvb, unsigned offset, uint32_t lvt, uint64_t *val) |
5999 | 56.2k | { |
6000 | 56.2k | bool valid = false; |
6001 | 56.2k | int64_t value = 0; |
6002 | 56.2k | uint8_t data; |
6003 | | |
6004 | 56.2k | if (lvt && (lvt <= 8)) { |
6005 | 20.6k | valid = true; |
6006 | 76.4k | for (unsigned i = 0; i < lvt; i++) { |
6007 | 55.8k | data = tvb_get_uint8(tvb, offset+i); |
6008 | 55.8k | value = (value << 8) + data; |
6009 | 55.8k | } |
6010 | 20.6k | *val = value; |
6011 | 20.6k | } |
6012 | | |
6013 | 56.2k | return valid; |
6014 | 56.2k | } |
6015 | | |
6016 | | /* BACnet Signed Value uses 2's complement notation, but with a twist: |
6017 | | All signed integers shall be encoded in the smallest number of octets |
6018 | | possible. That is, the first octet of any multi-octet encoded value |
6019 | | shall not be X'00' if the most significant bit (bit 7) of the second |
6020 | | octet is 0, and the first octet shall not be X'FF' if the most |
6021 | | significant bit of the second octet is 1. ASHRAE-135-2004-20.2.5 */ |
6022 | | static bool |
6023 | | fSigned64(tvbuff_t *tvb, unsigned offset, uint32_t lvt, int64_t *val) |
6024 | 8.83k | { |
6025 | 8.83k | bool valid = false; |
6026 | 8.83k | int64_t value = 0; |
6027 | 8.83k | uint8_t data; |
6028 | 8.83k | uint32_t i; |
6029 | | |
6030 | | /* we can only handle 7 bytes for a 64-bit value due to signed-ness */ |
6031 | 8.83k | if (lvt && (lvt <= 7)) { |
6032 | 3.66k | valid = true; |
6033 | 3.66k | data = tvb_get_uint8(tvb, offset); |
6034 | 3.66k | if ((data & 0x80) != 0) |
6035 | 721 | value = (~UINT64_C(0) << 8) | data; |
6036 | 2.94k | else |
6037 | 2.94k | value = data; |
6038 | 10.0k | for (i = 1; i < lvt; i++) { |
6039 | 6.37k | data = tvb_get_uint8(tvb, offset+i); |
6040 | 6.37k | value = ((uint64_t)value << 8) | data; |
6041 | 6.37k | } |
6042 | 3.66k | *val = value; |
6043 | 3.66k | } |
6044 | | |
6045 | 8.83k | return valid; |
6046 | 8.83k | } |
6047 | | |
6048 | | static unsigned |
6049 | | fTagHeaderTree(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, |
6050 | | unsigned offset, uint8_t *tag_no, uint8_t* tag_info, uint32_t *lvt) |
6051 | 1.45M | { |
6052 | 1.45M | proto_item *ti = NULL; |
6053 | 1.45M | uint8_t tag; |
6054 | 1.45M | uint8_t value; |
6055 | 1.45M | unsigned tag_len = 1; |
6056 | 1.45M | unsigned lvt_len = 1; /* used for tree display of lvt */ |
6057 | 1.45M | unsigned lvt_offset; /* used for tree display of lvt */ |
6058 | | |
6059 | 1.45M | lvt_offset = offset; |
6060 | 1.45M | tag = tvb_get_uint8(tvb, offset); |
6061 | 1.45M | *tag_info = 0; |
6062 | 1.45M | *lvt = tag & 0x07; |
6063 | | |
6064 | | /* To solve the problem of lvt values of 6/7 being indeterminate - it */ |
6065 | | /* can mean open/close tag or length of 6/7 after the length is */ |
6066 | | /* computed below - store whole tag info, not just context bit. */ |
6067 | 1.45M | if (tag_is_context_specific(tag)) *tag_info = tag & 0x0F; |
6068 | 1.45M | *tag_no = tag >> 4; |
6069 | 1.45M | if (tag_is_extended_tag_number(tag)) { |
6070 | 48.7k | *tag_no = tvb_get_uint8(tvb, offset + tag_len++); |
6071 | 48.7k | } |
6072 | 1.45M | if (tag_is_extended_value(tag)) { /* length is more than 4 Bytes */ |
6073 | 56.1k | lvt_offset += tag_len; |
6074 | 56.1k | value = tvb_get_uint8(tvb, lvt_offset); |
6075 | 56.1k | tag_len++; |
6076 | 56.1k | if (value == 254) { /* length is encoded with 16 Bits */ |
6077 | 163 | *lvt = tvb_get_ntohs(tvb, lvt_offset+1); |
6078 | 163 | tag_len += 2; |
6079 | 163 | lvt_len += 2; |
6080 | 55.9k | } else if (value == 255) { /* length is encoded with 32 Bits */ |
6081 | 2.05k | *lvt = tvb_get_ntohl(tvb, lvt_offset+1); |
6082 | 2.05k | tag_len += 4; |
6083 | 2.05k | lvt_len += 4; |
6084 | 2.05k | } else |
6085 | 53.8k | *lvt = value; |
6086 | 56.1k | } |
6087 | | |
6088 | 1.45M | if (tree) { |
6089 | 549k | proto_tree *subtree; |
6090 | 549k | if (tag_is_opening(tag)) { |
6091 | 47.7k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, tag_len, |
6092 | 47.7k | ett_bacapp_tag, &ti, "{[%u]", *tag_no ); |
6093 | 502k | } else if (tag_is_closing(tag)) { |
6094 | 27.9k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, tag_len, |
6095 | 27.9k | ett_bacapp_tag, &ti, "}[%u]", *tag_no ); |
6096 | 474k | } else if (tag_is_context_specific(tag)) { |
6097 | 122k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, tag_len, |
6098 | 122k | ett_bacapp_tag, &ti, |
6099 | 122k | "Context Tag: %u, Length/Value/Type: %u", *tag_no, *lvt); |
6100 | 351k | } else { |
6101 | 351k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, tag_len, |
6102 | 351k | ett_bacapp_tag, &ti, |
6103 | 351k | "Application Tag: %s, Length/Value/Type: %u", |
6104 | 351k | val_to_str(pinfo->pool, *tag_no, BACnetApplicationTagNumber, |
6105 | 351k | ASHRAE_Reserved_Fmt), |
6106 | 351k | *lvt); |
6107 | 351k | } |
6108 | | |
6109 | | /* details if needed */ |
6110 | 549k | proto_tree_add_item(subtree, hf_BACnetTagClass, tvb, offset, 1, ENC_BIG_ENDIAN); |
6111 | 549k | if (tag_is_extended_tag_number(tag)) { |
6112 | 18.0k | proto_tree_add_uint_format(subtree, |
6113 | 18.0k | hf_BACnetContextTagNumber, |
6114 | 18.0k | tvb, offset, 1, tag, |
6115 | 18.0k | "Extended Tag Number"); |
6116 | 18.0k | proto_tree_add_item(subtree, |
6117 | 18.0k | hf_BACnetExtendedTagNumber, |
6118 | 18.0k | tvb, offset + 1, 1, ENC_BIG_ENDIAN); |
6119 | 531k | } else { |
6120 | 531k | if (tag_is_context_specific(tag)) |
6121 | 156k | proto_tree_add_item(subtree, |
6122 | 156k | hf_BACnetContextTagNumber, |
6123 | 156k | tvb, offset, 1, ENC_BIG_ENDIAN); |
6124 | 375k | else |
6125 | 375k | proto_tree_add_item(subtree, |
6126 | 375k | hf_BACnetApplicationTagNumber, |
6127 | 375k | tvb, offset, 1, ENC_BIG_ENDIAN); |
6128 | 531k | } |
6129 | 549k | if (tag_is_closing(tag) || tag_is_opening(tag)) |
6130 | 75.7k | proto_tree_add_item(subtree, |
6131 | 75.7k | hf_BACnetNamedTag, |
6132 | 75.7k | tvb, offset, 1, ENC_BIG_ENDIAN); |
6133 | 474k | else if (tag_is_extended_value(tag)) { |
6134 | 21.8k | proto_tree_add_item(subtree, |
6135 | 21.8k | hf_BACnetNamedTag, |
6136 | 21.8k | tvb, offset, 1, ENC_BIG_ENDIAN); |
6137 | 21.8k | proto_tree_add_uint(subtree, hf_bacapp_tag_lvt, |
6138 | 21.8k | tvb, lvt_offset, lvt_len, *lvt); |
6139 | 21.8k | } else |
6140 | 452k | proto_tree_add_uint(subtree, hf_bacapp_tag_lvt, |
6141 | 452k | tvb, lvt_offset, lvt_len, *lvt); |
6142 | 549k | } /* if (tree) */ |
6143 | | |
6144 | 1.45M | if (*lvt > tvb_reported_length(tvb)) { |
6145 | 10.9k | expert_add_info_format(pinfo, ti, &ei_bacapp_bad_length, |
6146 | 10.9k | "LVT length too long: %d > %d", *lvt, |
6147 | 10.9k | tvb_reported_length(tvb)); |
6148 | 10.9k | *lvt = 1; |
6149 | 10.9k | } |
6150 | | |
6151 | 1.45M | return tag_len; |
6152 | 1.45M | } |
6153 | | |
6154 | | static unsigned |
6155 | | fTagHeader(tvbuff_t *tvb, packet_info *pinfo, unsigned offset, uint8_t *tag_no, uint8_t* tag_info, |
6156 | | uint32_t *lvt) |
6157 | 903k | { |
6158 | 903k | return fTagHeaderTree(tvb, pinfo, NULL, offset, tag_no, tag_info, lvt); |
6159 | 903k | } |
6160 | | |
6161 | | static unsigned |
6162 | | fNullTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label) |
6163 | 25.7k | { |
6164 | 25.7k | uint8_t tag_no, tag_info; |
6165 | 25.7k | uint32_t lvt; |
6166 | 25.7k | proto_tree *subtree; |
6167 | | |
6168 | 25.7k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, 1, ett_bacapp_tag, NULL, "%sNULL", label); |
6169 | 25.7k | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
6170 | | |
6171 | 25.7k | return offset + 1; |
6172 | 25.7k | } |
6173 | | |
6174 | | static unsigned |
6175 | | fBooleanTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label) |
6176 | 14.9k | { |
6177 | 14.9k | uint8_t tag_no, tag_info; |
6178 | 14.9k | uint32_t lvt = 0; |
6179 | 14.9k | proto_tree *subtree; |
6180 | 14.9k | unsigned bool_len = 1; |
6181 | | |
6182 | 14.9k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
6183 | 14.9k | if (tag_info && lvt == 1) { |
6184 | 512 | lvt = tvb_get_uint8(tvb, offset+1); |
6185 | 512 | ++bool_len; |
6186 | 512 | } |
6187 | | |
6188 | 14.9k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, bool_len, |
6189 | 14.9k | ett_bacapp_tag, NULL, "%s%s", label, lvt == 0 ? "FALSE" : "TRUE"); |
6190 | 14.9k | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
6191 | | |
6192 | 14.9k | return offset + bool_len; |
6193 | 14.9k | } |
6194 | | |
6195 | | static unsigned |
6196 | | fUnsignedTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label) |
6197 | 55.3k | { |
6198 | 55.3k | uint64_t val = 0; |
6199 | 55.3k | uint8_t tag_no, tag_info; |
6200 | 55.3k | uint32_t lvt; |
6201 | 55.3k | unsigned tag_len; |
6202 | 55.3k | proto_tree *subtree; |
6203 | | |
6204 | 55.3k | tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
6205 | | /* only support up to an 8 byte (64-bit) integer */ |
6206 | 55.3k | if (fUnsigned64(tvb, offset + tag_len, lvt, &val)) |
6207 | 19.9k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, |
6208 | 19.9k | ett_bacapp_tag, NULL, "%s(Unsigned) %" PRIu64, label, val); |
6209 | 35.3k | else |
6210 | 35.3k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, |
6211 | 35.3k | ett_bacapp_tag, NULL, "%s - %u octets (Unsigned)", label, lvt); |
6212 | 55.3k | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
6213 | | |
6214 | 55.3k | return offset+tag_len+lvt; |
6215 | 55.3k | } |
6216 | | |
6217 | | static unsigned |
6218 | | fDevice_Instance(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, int hf) |
6219 | 105 | { |
6220 | 105 | uint8_t tag_no, tag_info; |
6221 | 105 | uint32_t lvt, safe_lvt; |
6222 | 105 | unsigned tag_len; |
6223 | 105 | proto_item *ti; |
6224 | 105 | proto_tree *subtree; |
6225 | | |
6226 | 105 | tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
6227 | | |
6228 | 105 | if (lvt > 4) |
6229 | 29 | safe_lvt = 4; |
6230 | 76 | else |
6231 | 76 | safe_lvt = lvt; |
6232 | | |
6233 | 105 | ti = proto_tree_add_item(tree, hf, tvb, offset+tag_len, safe_lvt, ENC_BIG_ENDIAN); |
6234 | | |
6235 | 105 | if (lvt != safe_lvt) |
6236 | 29 | expert_add_info_format(pinfo, ti, &ei_bacapp_bad_length, |
6237 | 29 | "This field claims to be an impossible %u bytes, while the max is %u", lvt, safe_lvt); |
6238 | | |
6239 | 105 | subtree = proto_item_add_subtree(ti, ett_bacapp_tag); |
6240 | 105 | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
6241 | | |
6242 | 105 | return offset+tag_len+lvt; |
6243 | 105 | } |
6244 | | |
6245 | | /* set split_val to zero when not needed */ |
6246 | | static unsigned |
6247 | | fEnumeratedTagSplit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, |
6248 | | unsigned offset, const char *label, const value_string *vs, uint32_t split_val) |
6249 | 32.1k | { |
6250 | 32.1k | uint32_t val = 0; |
6251 | 32.1k | uint8_t tag_no, tag_info; |
6252 | 32.1k | uint32_t lvt; |
6253 | 32.1k | unsigned tag_len; |
6254 | 32.1k | proto_tree *subtree; |
6255 | | |
6256 | 32.1k | tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
6257 | | /* only support up to a 4 byte (32-bit) enumeration */ |
6258 | 32.1k | if (fUnsigned32(tvb, offset+tag_len, lvt, &val)) { |
6259 | 9.46k | if (vs) |
6260 | 8.08k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, |
6261 | 8.08k | ett_bacapp_tag, NULL, "%s %s (%u)", label, |
6262 | 8.08k | val_to_split_str(pinfo->pool, val, split_val, vs, |
6263 | 8.08k | ASHRAE_Reserved_Fmt, Vendor_Proprietary_Fmt), val); |
6264 | 1.38k | else |
6265 | 1.38k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, |
6266 | 1.38k | ett_bacapp_tag, NULL, "%s %u", label, val); |
6267 | 22.7k | } else { |
6268 | 22.7k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, |
6269 | 22.7k | ett_bacapp_tag, NULL, "%s - %u octets (enumeration)", label, lvt); |
6270 | 22.7k | } |
6271 | | |
6272 | 32.1k | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
6273 | | |
6274 | 32.1k | return offset+tag_len+lvt; |
6275 | 32.1k | } |
6276 | | |
6277 | | static unsigned |
6278 | | fEnumeratedTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, |
6279 | | unsigned offset, const char *label, const value_string *vs) |
6280 | 12.1k | { |
6281 | 12.1k | return fEnumeratedTagSplit(tvb, pinfo, tree, offset, label, vs, 0); |
6282 | 12.1k | } |
6283 | | |
6284 | | static unsigned |
6285 | | fSignedTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label) |
6286 | 7.77k | { |
6287 | 7.77k | int64_t val = 0; |
6288 | 7.77k | uint8_t tag_no, tag_info; |
6289 | 7.77k | uint32_t lvt; |
6290 | 7.77k | unsigned tag_len; |
6291 | 7.77k | proto_tree *subtree; |
6292 | | |
6293 | 7.77k | tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
6294 | 7.77k | if (fSigned64(tvb, offset + tag_len, lvt, &val)) |
6295 | 3.00k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, |
6296 | 3.00k | ett_bacapp_tag, NULL, "%s(Signed) %" PRId64, label, val); |
6297 | 4.77k | else |
6298 | 4.77k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, |
6299 | 4.77k | ett_bacapp_tag, NULL, "%s - %u octets (Signed)", label, lvt); |
6300 | 7.77k | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
6301 | | |
6302 | 7.77k | return offset+tag_len+lvt; |
6303 | 7.77k | } |
6304 | | |
6305 | | static unsigned |
6306 | | fRealTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label) |
6307 | 7.10k | { |
6308 | 7.10k | uint8_t tag_no, tag_info; |
6309 | 7.10k | uint32_t lvt; |
6310 | 7.10k | unsigned tag_len; |
6311 | 7.10k | float f_val; |
6312 | 7.10k | proto_tree *subtree; |
6313 | | |
6314 | 7.10k | tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
6315 | 7.10k | f_val = tvb_get_ntohieee_float(tvb, offset+tag_len); |
6316 | 7.10k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, 4+tag_len, |
6317 | 7.10k | ett_bacapp_tag, NULL, "%s%f (Real)", label, f_val); |
6318 | 7.10k | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
6319 | | |
6320 | 7.10k | return offset+tag_len+4; |
6321 | 7.10k | } |
6322 | | |
6323 | | static unsigned |
6324 | | fDoubleTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label) |
6325 | 1.77k | { |
6326 | 1.77k | uint8_t tag_no, tag_info; |
6327 | 1.77k | uint32_t lvt; |
6328 | 1.77k | unsigned tag_len; |
6329 | 1.77k | double d_val; |
6330 | 1.77k | proto_tree *subtree; |
6331 | | |
6332 | 1.77k | tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
6333 | 1.77k | d_val = tvb_get_ntohieee_double(tvb, offset+tag_len); |
6334 | 1.77k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, 8+tag_len, |
6335 | 1.77k | ett_bacapp_tag, NULL, "%s%f (Double)", label, d_val); |
6336 | 1.77k | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
6337 | | |
6338 | 1.77k | return offset+tag_len+8; |
6339 | 1.77k | } |
6340 | | |
6341 | | static unsigned |
6342 | | fProcessId(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
6343 | 35.2k | { |
6344 | 35.2k | uint32_t val = 0, lvt; |
6345 | 35.2k | uint8_t tag_no, tag_info; |
6346 | 35.2k | proto_item *ti; |
6347 | 35.2k | proto_tree *subtree; |
6348 | 35.2k | unsigned tag_len; |
6349 | | |
6350 | 35.2k | tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
6351 | 35.2k | if (fUnsigned32(tvb, offset+tag_len, lvt, &val)) |
6352 | 6.71k | { |
6353 | 6.71k | ti = proto_tree_add_uint(tree, hf_bacapp_tag_ProcessId, |
6354 | 6.71k | tvb, offset, lvt+tag_len, val); |
6355 | 6.71k | subtree = proto_item_add_subtree(ti, ett_bacapp_tag); |
6356 | 6.71k | } |
6357 | 28.5k | else |
6358 | 28.5k | { |
6359 | 28.5k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, |
6360 | 28.5k | ett_bacapp_tag, NULL, "Process Identifier - %u octets (Signed)", lvt); |
6361 | 28.5k | } |
6362 | 35.2k | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
6363 | 35.2k | offset += tag_len + lvt; |
6364 | | |
6365 | 35.2k | return offset; |
6366 | 35.2k | } |
6367 | | |
6368 | | static unsigned |
6369 | | fPresentValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const value_string *vs, uint32_t split_val, BacappPresentValueType type) |
6370 | 21.9k | { |
6371 | | // tag vars |
6372 | 21.9k | uint32_t lvt; |
6373 | 21.9k | uint8_t tag_no, tag_info; |
6374 | 21.9k | unsigned tag_len; |
6375 | 21.9k | unsigned curr_offset = offset; |
6376 | | // tree vars |
6377 | 21.9k | proto_item *tree_item = NULL; |
6378 | 21.9k | proto_tree *subtree = NULL; |
6379 | | // dissection vars |
6380 | 21.9k | unsigned bool_len = 1; |
6381 | 21.9k | uint64_t unsigned_val = 0; |
6382 | 21.9k | int64_t signed_val = 0; |
6383 | 21.9k | float float_val; |
6384 | 21.9k | double double_val; |
6385 | 21.9k | uint32_t enum_index = 0; |
6386 | 21.9k | uint32_t object_id; |
6387 | | |
6388 | 21.9k | tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
6389 | 21.9k | switch(type) { |
6390 | 9.81k | case BACAPP_PRESENT_VALUE_NULL: |
6391 | 9.81k | tree_item = proto_tree_add_string(tree, hf_bacapp_present_value_null, tvb, offset, lvt+tag_len, "NULL"); |
6392 | 9.81k | curr_offset += 1; |
6393 | 9.81k | break; |
6394 | 1.21k | case BACAPP_PRESENT_VALUE_BOOL: |
6395 | 1.21k | if (tag_info && lvt == 1) { |
6396 | 0 | lvt = tvb_get_uint8(tvb, offset+1); |
6397 | 0 | bool_len++; |
6398 | 0 | } |
6399 | 1.21k | tree_item = proto_tree_add_boolean(tree, hf_bacapp_present_value_bool, tvb, offset, bool_len, lvt); |
6400 | 1.21k | curr_offset += bool_len; |
6401 | 1.21k | break; |
6402 | 951 | case BACAPP_PRESENT_VALUE_UNSIGNED: |
6403 | 951 | if (fUnsigned64(tvb, offset + tag_len, lvt, &unsigned_val)) |
6404 | 444 | tree_item = proto_tree_add_uint64(tree, hf_bacapp_present_value_unsigned, tvb, offset, lvt+tag_len, unsigned_val); |
6405 | 951 | curr_offset += tag_len + lvt; |
6406 | 951 | break; |
6407 | 1.06k | case BACAPP_PRESENT_VALUE_SIGNED: |
6408 | 1.06k | if (fSigned64(tvb, offset + tag_len, lvt, &signed_val)) |
6409 | 631 | tree_item = proto_tree_add_int64(tree, hf_bacapp_present_value_signed, tvb, offset, lvt+tag_len, signed_val); |
6410 | 1.06k | curr_offset += tag_len + lvt; |
6411 | 1.06k | break; |
6412 | 610 | case BACAPP_PRESENT_VALUE_REAL: |
6413 | 610 | float_val = tvb_get_ntohieee_float(tvb, offset+tag_len); |
6414 | 610 | double_val = (double) float_val; |
6415 | 610 | tree_item = proto_tree_add_double(tree, hf_bacapp_present_value_real, tvb, offset, lvt+tag_len, double_val); |
6416 | 610 | curr_offset += tag_len + lvt; |
6417 | 610 | break; |
6418 | 459 | case BACAPP_PRESENT_VALUE_DOUBLE: |
6419 | 459 | double_val = tvb_get_ntohieee_double(tvb, offset+tag_len); |
6420 | 459 | tree_item = proto_tree_add_double(tree, hf_bacapp_present_value_double, tvb, offset, lvt+tag_len, double_val); |
6421 | 459 | curr_offset += tag_len + lvt; |
6422 | 459 | break; |
6423 | 975 | case BACAPP_PRESENT_VALUE_OCTET_STRING: |
6424 | 975 | if (lvt > 0) |
6425 | 408 | tree_item = proto_tree_add_item(tree, hf_bacapp_present_value_octet_string, tvb, offset, lvt+tag_len, ENC_NA); |
6426 | 975 | curr_offset += tag_len + lvt; |
6427 | 975 | break; |
6428 | 448 | case BACAPP_PRESENT_VALUE_CHARACTER_STRING: |
6429 | 448 | curr_offset = fCharacterStringBase(tvb, pinfo, tree, offset, NULL, true, false); |
6430 | 448 | break; |
6431 | 746 | case BACAPP_PRESENT_VALUE_BIT_STRING: |
6432 | 746 | curr_offset = fBitStringTagVSBase(tvb, pinfo, tree, offset, NULL, NULL, true); |
6433 | 746 | break; |
6434 | 4.09k | case BACAPP_PRESENT_VALUE_ENUM: |
6435 | 4.09k | if (fUnsigned32(tvb, offset+tag_len, lvt, &enum_index)) { |
6436 | 1.83k | if (vs) { |
6437 | 1.44k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, ett_bacapp_tag, NULL, |
6438 | 1.44k | "Present Value (enum value): %s", |
6439 | 1.44k | val_to_split_str(pinfo->pool, enum_index, |
6440 | 1.44k | split_val, vs, |
6441 | 1.44k | ASHRAE_Reserved_Fmt, Vendor_Proprietary_Fmt)); |
6442 | 1.44k | proto_tree_add_uint(subtree, hf_bacapp_present_value_enum_index, tvb, offset, lvt+tag_len, enum_index); |
6443 | 1.44k | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
6444 | 1.44k | } else { |
6445 | 386 | tree_item = proto_tree_add_uint(tree, hf_bacapp_present_value_enum_index, tvb, offset, lvt+tag_len, enum_index); |
6446 | 386 | } |
6447 | 1.83k | } |
6448 | 4.09k | curr_offset += tag_len + lvt; |
6449 | 4.09k | break; |
6450 | 389 | case BACAPP_PRESENT_VALUE_DATE: |
6451 | 389 | curr_offset = fDate(tvb, pinfo, tree, offset, "Date: "); |
6452 | 389 | break; |
6453 | 550 | case BACAPP_PRESENT_VALUE_TIME: |
6454 | 550 | curr_offset = fTime(tvb, pinfo, tree, offset, "Time: "); |
6455 | 550 | break; |
6456 | 602 | case BACAPP_PRESENT_VALUE_OBJECT_IDENTIFIER: |
6457 | 602 | object_id = tvb_get_ntohl(tvb, offset+tag_len); |
6458 | 602 | object_type = object_id_type(object_id); |
6459 | 602 | subtree = proto_tree_add_subtree_format(tree, tvb, offset, tag_len + 4, ett_bacapp_tag, NULL, |
6460 | 602 | "Present Value (enum value): %s", |
6461 | 602 | val_to_split_str(pinfo->pool, object_type, |
6462 | 602 | 128, BACnetObjectType, |
6463 | 602 | ASHRAE_Reserved_Fmt, |
6464 | 602 | Vendor_Proprietary_Fmt)); |
6465 | 602 | proto_tree_add_uint(subtree, hf_bacapp_present_value_enum_index, tvb, offset, lvt+tag_len, object_type); |
6466 | 602 | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
6467 | 602 | curr_offset += tag_len + lvt; |
6468 | 602 | break; |
6469 | 0 | default: |
6470 | 0 | curr_offset += tag_len + lvt; |
6471 | 0 | break; |
6472 | 21.9k | } |
6473 | | |
6474 | 21.7k | if (tree_item != NULL && subtree == NULL) { |
6475 | 13.9k | subtree = proto_item_add_subtree(tree_item, ett_bacapp_value); |
6476 | 13.9k | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
6477 | 13.9k | } |
6478 | | |
6479 | 21.7k | return curr_offset; |
6480 | 21.9k | } |
6481 | | |
6482 | | static unsigned |
6483 | | fEventType(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
6484 | 4.30k | { |
6485 | 4.30k | uint32_t val = 0, lvt; |
6486 | 4.30k | uint8_t tag_no, tag_info; |
6487 | 4.30k | proto_item *ti; |
6488 | 4.30k | proto_tree *subtree; |
6489 | 4.30k | unsigned tag_len; |
6490 | | |
6491 | 4.30k | tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
6492 | 4.30k | if (fUnsigned32(tvb, offset+tag_len, lvt, &val)) |
6493 | 2.71k | { |
6494 | 2.71k | ti = proto_tree_add_uint(tree, hf_bacapp_event_type, |
6495 | 2.71k | tvb, offset, lvt+tag_len, val); |
6496 | 2.71k | subtree = proto_item_add_subtree(ti, ett_bacapp_tag); |
6497 | 2.71k | } |
6498 | 1.59k | else |
6499 | 1.59k | { |
6500 | 1.59k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, |
6501 | 1.59k | ett_bacapp_tag, NULL, "Event Type - %u octets (Signed)", lvt); |
6502 | 1.59k | } |
6503 | 4.30k | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
6504 | 4.30k | offset += tag_len + lvt; |
6505 | | |
6506 | 4.30k | return offset; |
6507 | 4.30k | } |
6508 | | |
6509 | | static unsigned |
6510 | | fNotifyType(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
6511 | 5.21k | { |
6512 | 5.21k | uint32_t val = 0, lvt; |
6513 | 5.21k | uint8_t tag_no, tag_info; |
6514 | 5.21k | proto_item *ti; |
6515 | 5.21k | proto_tree *subtree; |
6516 | 5.21k | unsigned tag_len; |
6517 | | |
6518 | 5.21k | tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
6519 | 5.21k | if (fUnsigned32(tvb, offset+tag_len, lvt, &val)) |
6520 | 2.12k | { |
6521 | 2.12k | ti = proto_tree_add_uint(tree, hf_bacapp_notify_type, |
6522 | 2.12k | tvb, offset, lvt+tag_len, val); |
6523 | 2.12k | subtree = proto_item_add_subtree(ti, ett_bacapp_tag); |
6524 | 2.12k | } |
6525 | 3.09k | else |
6526 | 3.09k | { |
6527 | 3.09k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, |
6528 | 3.09k | ett_bacapp_tag, NULL, "Notify Type - %u octets (Signed)", lvt); |
6529 | 3.09k | } |
6530 | 5.21k | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
6531 | 5.21k | offset += tag_len + lvt; |
6532 | | |
6533 | 5.21k | return offset; |
6534 | 5.21k | } |
6535 | | |
6536 | | static unsigned |
6537 | | fToState(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
6538 | 3.37k | { |
6539 | 3.37k | uint32_t val = 0, lvt; |
6540 | 3.37k | uint8_t tag_no, tag_info; |
6541 | 3.37k | proto_item *ti; |
6542 | 3.37k | proto_tree *subtree; |
6543 | 3.37k | unsigned tag_len; |
6544 | | |
6545 | 3.37k | tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
6546 | 3.37k | if (fUnsigned32(tvb, offset+tag_len, lvt, &val)) |
6547 | 1.51k | { |
6548 | 1.51k | ti = proto_tree_add_uint(tree, hf_bacapp_tag_to_state, |
6549 | 1.51k | tvb, offset, lvt+tag_len, val); |
6550 | 1.51k | subtree = proto_item_add_subtree(ti, ett_bacapp_tag); |
6551 | 1.51k | } |
6552 | 1.85k | else |
6553 | 1.85k | { |
6554 | 1.85k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, |
6555 | 1.85k | ett_bacapp_tag, NULL, "To State - %u octets (Signed)", lvt); |
6556 | 1.85k | } |
6557 | 3.37k | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
6558 | 3.37k | offset += tag_len + lvt; |
6559 | | |
6560 | 3.37k | return offset; |
6561 | 3.37k | } |
6562 | | |
6563 | | static unsigned |
6564 | | fFromState(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
6565 | 2.81k | { |
6566 | 2.81k | uint32_t val = 0, lvt; |
6567 | 2.81k | uint8_t tag_no, tag_info; |
6568 | 2.81k | proto_item *ti; |
6569 | 2.81k | proto_tree *subtree; |
6570 | 2.81k | unsigned tag_len; |
6571 | | |
6572 | 2.81k | tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
6573 | 2.81k | if (fUnsigned32(tvb, offset+tag_len, lvt, &val)) |
6574 | 1.33k | { |
6575 | 1.33k | ti = proto_tree_add_uint(tree, hf_bacapp_tag_from_state, |
6576 | 1.33k | tvb, offset, lvt+tag_len, val); |
6577 | 1.33k | subtree = proto_item_add_subtree(ti, ett_bacapp_tag); |
6578 | 1.33k | } |
6579 | 1.48k | else |
6580 | 1.48k | { |
6581 | 1.48k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, |
6582 | 1.48k | ett_bacapp_tag, NULL, "From State - %u octets (Signed)", lvt); |
6583 | 1.48k | } |
6584 | 2.81k | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
6585 | 2.81k | offset += tag_len + lvt; |
6586 | | |
6587 | 2.81k | return offset; |
6588 | 2.81k | } |
6589 | | |
6590 | | static unsigned |
6591 | | fTimeSpan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label) |
6592 | 24.7k | { |
6593 | 24.7k | uint32_t val = 0, lvt; |
6594 | 24.7k | uint8_t tag_no, tag_info; |
6595 | 24.7k | proto_tree *subtree; |
6596 | 24.7k | unsigned tag_len; |
6597 | | |
6598 | 24.7k | tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
6599 | 24.7k | if (fUnsigned32(tvb, offset+tag_len, lvt, &val)) |
6600 | 3.98k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, |
6601 | 3.98k | ett_bacapp_tag, NULL, |
6602 | 3.98k | "%s (hh.mm.ss): %d.%02d.%02d%s", |
6603 | 3.98k | label, |
6604 | 3.98k | (val / 3600), ((val % 3600) / 60), (val % 60), |
6605 | 3.98k | val == 0 ? " (indefinite)" : ""); |
6606 | 20.7k | else |
6607 | 20.7k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, |
6608 | 20.7k | ett_bacapp_tag, NULL, |
6609 | 20.7k | "%s - %u octets (Signed)", label, lvt); |
6610 | 24.7k | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
6611 | | |
6612 | 24.7k | return offset+tag_len+lvt; |
6613 | 24.7k | } |
6614 | | |
6615 | | static unsigned |
6616 | | fWeekNDay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
6617 | 219 | { |
6618 | 219 | uint32_t month, weekOfMonth, dayOfWeek; |
6619 | 219 | uint8_t tag_no, tag_info; |
6620 | 219 | uint32_t lvt; |
6621 | 219 | unsigned tag_len; |
6622 | 219 | proto_tree *subtree; |
6623 | | |
6624 | 219 | tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
6625 | 219 | month = tvb_get_uint8(tvb, offset+tag_len); |
6626 | 219 | weekOfMonth = tvb_get_uint8(tvb, offset+tag_len+1); |
6627 | 219 | dayOfWeek = tvb_get_uint8(tvb, offset+tag_len+2); |
6628 | 219 | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, |
6629 | 219 | ett_bacapp_tag, NULL, "%s %s, %s", |
6630 | 219 | val_to_str(pinfo->pool, month, months, "month (%d) not found"), |
6631 | 219 | val_to_str(pinfo->pool, weekOfMonth, weekofmonth, "week of month (%d) not found"), |
6632 | 219 | val_to_str(pinfo->pool, dayOfWeek, day_of_week, "day of week (%d) not found")); |
6633 | 219 | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
6634 | | |
6635 | 219 | return offset+tag_len+lvt; |
6636 | 219 | } |
6637 | | |
6638 | | static unsigned |
6639 | | fDate(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label) |
6640 | 10.2k | { |
6641 | 10.2k | uint32_t year, month, day, weekday; |
6642 | 10.2k | uint8_t tag_no, tag_info; |
6643 | 10.2k | uint32_t lvt; |
6644 | 10.2k | unsigned tag_len; |
6645 | 10.2k | proto_tree *subtree; |
6646 | | |
6647 | 10.2k | tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
6648 | 10.2k | year = tvb_get_uint8(tvb, offset+tag_len); |
6649 | 10.2k | month = tvb_get_uint8(tvb, offset+tag_len+1); |
6650 | 10.2k | day = tvb_get_uint8(tvb, offset+tag_len+2); |
6651 | 10.2k | weekday = tvb_get_uint8(tvb, offset+tag_len+3); |
6652 | 10.2k | if ((year == 255) && (day == 255) && (month == 255) && (weekday == 255)) { |
6653 | 74 | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, |
6654 | 74 | ett_bacapp_tag, NULL, |
6655 | 74 | "%sany", label); |
6656 | 74 | } |
6657 | 10.1k | else if (year != 255) { |
6658 | 9.90k | year += 1900; |
6659 | 9.90k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, |
6660 | 9.90k | ett_bacapp_tag, NULL, |
6661 | 9.90k | "%s%s %d, %d, (Day of Week = %s)", |
6662 | 9.90k | label, val_to_str(pinfo->pool, month, |
6663 | 9.90k | months, |
6664 | 9.90k | "month (%d) not found"), |
6665 | 9.90k | day, year, val_to_str(pinfo->pool, weekday, |
6666 | 9.90k | day_of_week, |
6667 | 9.90k | "(%d) not found")); |
6668 | 9.90k | } else { |
6669 | 227 | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, |
6670 | 227 | ett_bacapp_tag, NULL, |
6671 | 227 | "%s%s %d, any year, (Day of Week = %s)", |
6672 | 227 | label, val_to_str(pinfo->pool, month, months, "month (%d) not found"), |
6673 | 227 | day, val_to_str(pinfo->pool, weekday, day_of_week, "(%d) not found")); |
6674 | 227 | } |
6675 | 10.2k | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
6676 | | |
6677 | 10.2k | return offset+tag_len+lvt; |
6678 | 10.2k | } |
6679 | | |
6680 | | static unsigned |
6681 | | fTime(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label) |
6682 | 15.5k | { |
6683 | 15.5k | uint32_t hour, minute, second, msec, lvt; |
6684 | 15.5k | uint8_t tag_no, tag_info; |
6685 | 15.5k | unsigned tag_len; |
6686 | 15.5k | proto_tree *subtree; |
6687 | | |
6688 | 15.5k | tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
6689 | 15.5k | hour = tvb_get_uint8(tvb, offset+tag_len); |
6690 | 15.5k | minute = tvb_get_uint8(tvb, offset+tag_len+1); |
6691 | 15.5k | second = tvb_get_uint8(tvb, offset+tag_len+2); |
6692 | 15.5k | msec = tvb_get_uint8(tvb, offset+tag_len+3); |
6693 | 15.5k | if ((hour == 255) && (minute == 255) && (second == 255) && (msec == 255)) |
6694 | 73 | subtree = proto_tree_add_subtree_format(tree, tvb, offset, |
6695 | 73 | lvt+tag_len, ett_bacapp_tag, NULL, |
6696 | 73 | "%sany", label); |
6697 | 15.4k | else |
6698 | 15.4k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, |
6699 | 15.4k | ett_bacapp_tag, NULL, |
6700 | 15.4k | "%s%d:%02d:%02d.%d %s = %02d:%02d:%02d.%d", |
6701 | 15.4k | label, |
6702 | 15.4k | hour > 12 ? hour - 12 : hour, |
6703 | 15.4k | minute, second, msec, |
6704 | 15.4k | hour >= 12 ? "P.M." : "A.M.", |
6705 | 15.4k | hour, minute, second, msec); |
6706 | 15.5k | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
6707 | | |
6708 | 15.5k | return offset+tag_len+lvt; |
6709 | 15.5k | } |
6710 | | |
6711 | | static unsigned |
6712 | | fDateTime(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label) |
6713 | 6.76k | { |
6714 | 6.76k | proto_tree *subtree = tree; |
6715 | | |
6716 | 6.76k | if (label != NULL) { |
6717 | 6.76k | subtree = proto_tree_add_subtree(subtree, tvb, offset, 10, ett_bacapp_value, NULL, label); |
6718 | 6.76k | } |
6719 | 6.76k | offset = fDate(tvb, pinfo, subtree, offset, "Date: "); |
6720 | 6.76k | return fTime(tvb, pinfo, subtree, offset, "Time: "); |
6721 | 6.76k | } |
6722 | | |
6723 | | static unsigned |
6724 | | fTimeValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
6725 | 4 | { |
6726 | 4 | unsigned lastoffset = 0; |
6727 | 4 | uint8_t tag_no, tag_info; |
6728 | 4 | uint32_t lvt; |
6729 | | |
6730 | 20 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
6731 | 19 | lastoffset = offset; |
6732 | 19 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
6733 | 19 | if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */ |
6734 | 3 | return offset; |
6735 | 3 | } |
6736 | 16 | offset = fTime(tvb, pinfo, tree, offset, "Time: "); |
6737 | 16 | offset = fApplicationTypes(tvb, pinfo, tree, offset, "Value: "); |
6738 | | |
6739 | 16 | if (offset <= lastoffset) break; /* exit loop if nothing happens inside */ |
6740 | 16 | } |
6741 | 1 | return offset; |
6742 | 4 | } |
6743 | | |
6744 | | static unsigned |
6745 | | fCalendarEntry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
6746 | 1.87k | { |
6747 | 1.87k | uint8_t tag_no, tag_info; |
6748 | 1.87k | uint32_t lvt; |
6749 | | |
6750 | 1.87k | switch (fTagNo(tvb, offset)) { |
6751 | 1.37k | case 0: /* Date */ |
6752 | 1.37k | offset = fDate(tvb, pinfo, tree, offset, "Date: "); |
6753 | 1.37k | break; |
6754 | 166 | case 1: /* dateRange */ |
6755 | 166 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
6756 | 166 | offset = fDateRange(tvb, pinfo, tree, offset); |
6757 | 166 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
6758 | 166 | break; |
6759 | 219 | case 2: /* BACnetWeekNDay */ |
6760 | 219 | offset = fWeekNDay(tvb, pinfo, tree, offset); |
6761 | 219 | break; |
6762 | 122 | default: |
6763 | 122 | return offset; |
6764 | 1.87k | } |
6765 | | |
6766 | 1.75k | return offset; |
6767 | 1.87k | } |
6768 | | |
6769 | | static unsigned |
6770 | | fEventTimeStamps( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
6771 | 69 | { |
6772 | 69 | uint32_t lvt = 0; |
6773 | 69 | proto_tree* subtree = tree; |
6774 | | |
6775 | 69 | if (tvb_reported_length_remaining(tvb, offset) > 0) { |
6776 | 69 | subtree = proto_tree_add_subtree(tree, tvb, offset, lvt, ett_bacapp_tag, NULL, "eventTimeStamps"); |
6777 | | |
6778 | 69 | offset = fTimeStamp(tvb, pinfo, subtree, offset, "TO-OFFNORMAL timestamp: "); |
6779 | 69 | offset = fTimeStamp(tvb, pinfo, subtree, offset, "TO-FAULT timestamp: "); |
6780 | 69 | offset = fTimeStamp(tvb, pinfo, subtree, offset, "TO-NORMAL timestamp: "); |
6781 | 69 | } |
6782 | 69 | return offset; |
6783 | 69 | } |
6784 | | |
6785 | | static unsigned |
6786 | | fTimeStamp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label) |
6787 | 15.1k | { |
6788 | 15.1k | uint8_t tag_no = 0, tag_info = 0; |
6789 | 15.1k | uint32_t lvt = 0; |
6790 | | |
6791 | 15.1k | if (tvb_reported_length_remaining(tvb, offset) > 0) { /* don't loop, it's a CHOICE */ |
6792 | 15.0k | switch (fTagNo(tvb, offset)) { |
6793 | 6.61k | case 0: /* time */ |
6794 | 6.61k | offset = fTime(tvb, pinfo, tree, offset, label?label:"time: "); |
6795 | 6.61k | break; |
6796 | 1.05k | case 1: /* sequenceNumber */ |
6797 | 1.05k | offset = fUnsignedTag(tvb, pinfo, tree, offset, |
6798 | 1.05k | label?label:"sequence number: "); |
6799 | 1.05k | break; |
6800 | 470 | case 2: /* dateTime */ |
6801 | 470 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
6802 | 470 | offset = fDateTime(tvb, pinfo, tree, offset, label?label:"date time: "); |
6803 | 470 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
6804 | 470 | break; |
6805 | 6.95k | default: |
6806 | 6.95k | return offset; |
6807 | 15.0k | } |
6808 | 15.0k | } |
6809 | | |
6810 | 8.07k | return offset; |
6811 | 15.1k | } |
6812 | | |
6813 | | |
6814 | | static unsigned |
6815 | | fClientCOV(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
6816 | 225 | { |
6817 | 225 | if (tvb_reported_length_remaining(tvb, offset) > 0) { |
6818 | 225 | offset = fApplicationTypes(tvb, pinfo, tree, offset, "increment: "); |
6819 | 225 | } |
6820 | 225 | return offset; |
6821 | 225 | } |
6822 | | |
6823 | | static const value_string |
6824 | | BACnetDaysOfWeek [] = { |
6825 | | { 0, "Monday" }, |
6826 | | { 1, "Tuesday" }, |
6827 | | { 2, "Wednesday" }, |
6828 | | { 3, "Thursday" }, |
6829 | | { 4, "Friday" }, |
6830 | | { 5, "Saturday" }, |
6831 | | { 6, "Sunday" }, |
6832 | | { 0, NULL } |
6833 | | }; |
6834 | | |
6835 | | static unsigned |
6836 | | fDestination(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
6837 | 130 | { |
6838 | 130 | if (tvb_reported_length_remaining(tvb, offset) > 0) { |
6839 | 130 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, |
6840 | 130 | "valid Days: ", BACnetDaysOfWeek); |
6841 | 130 | offset = fTime(tvb, pinfo, tree, offset, "from time: "); |
6842 | 130 | offset = fTime(tvb, pinfo, tree, offset, "to time: "); |
6843 | 130 | offset = fRecipient(tvb, pinfo, tree, offset); |
6844 | 130 | offset = fProcessId(tvb, pinfo, tree, offset); |
6845 | 130 | offset = fApplicationTypes(tvb, pinfo, tree, offset, |
6846 | 130 | "issue confirmed notifications: "); |
6847 | 130 | offset = fBitStringTagVS(tvb, pinfo, tree, offset, |
6848 | 130 | "transitions: ", BACnetEventTransitionBits); |
6849 | 130 | } |
6850 | 130 | return offset; |
6851 | 130 | } |
6852 | | |
6853 | | |
6854 | | static unsigned |
6855 | | fOctetString(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label, uint32_t lvt) |
6856 | 3.54k | { |
6857 | 3.54k | char *tmp; |
6858 | 3.54k | unsigned start = offset; |
6859 | 3.54k | uint8_t tag_no, tag_info; |
6860 | 3.54k | proto_tree *subtree = tree; |
6861 | | |
6862 | 3.54k | offset += fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
6863 | | |
6864 | 3.54k | if (lvt > 0) { |
6865 | 1.78k | tmp = tvb_bytes_to_str(pinfo->pool, tvb, offset, lvt); |
6866 | 1.78k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt, |
6867 | 1.78k | ett_bacapp_tag, NULL, "%s %s", label, tmp); |
6868 | 1.78k | offset += lvt; |
6869 | 1.78k | } |
6870 | | |
6871 | 3.54k | fTagHeaderTree(tvb, pinfo, subtree, start, &tag_no, &tag_info, &lvt); |
6872 | | |
6873 | 3.54k | return offset; |
6874 | 3.54k | } |
6875 | | |
6876 | | static unsigned |
6877 | | fMacAddress(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label, uint32_t lvt) |
6878 | 1.00k | { |
6879 | 1.00k | unsigned start = offset; |
6880 | 1.00k | uint8_t tag_no, tag_info; |
6881 | 1.00k | proto_tree* subtree = tree; |
6882 | | |
6883 | 1.00k | offset += fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
6884 | | |
6885 | | /* just add the label, with the tagHeader information in its subtree */ |
6886 | 1.00k | subtree = proto_tree_add_subtree(tree, tvb, offset, lvt, ett_bacapp_tag, NULL, label); |
6887 | | |
6888 | 1.00k | if (lvt == 6) { /* we have 6 Byte IP Address with 4 Octets IPv4 and 2 Octets Port Information */ |
6889 | 153 | proto_tree_add_item(tree, hf_bacapp_tag_IPV4, tvb, offset, 4, ENC_BIG_ENDIAN); |
6890 | 153 | proto_tree_add_item(tree, hf_bacapp_tag_PORT, tvb, offset+4, 2, ENC_BIG_ENDIAN); |
6891 | 852 | } else if (lvt == 18) { /* we have 18 Byte IP Address with 16 Octets IPv6 and 2 Octets Port Information */ |
6892 | 3 | proto_tree_add_item(tree, hf_bacapp_tag_IPV6, tvb, offset, 16, ENC_NA); |
6893 | 3 | proto_tree_add_item(tree, hf_bacapp_tag_PORT, tvb, offset+16, 2, ENC_BIG_ENDIAN); |
6894 | 849 | } else { /* we have 1 Byte MS/TP Address or anything else interpreted as an address */ |
6895 | 849 | subtree = proto_tree_add_subtree(tree, tvb, offset, lvt, |
6896 | 849 | ett_bacapp_tag, NULL, tvb_bytes_to_str(pinfo->pool, tvb, offset, lvt)); |
6897 | 849 | } |
6898 | 1.00k | offset += lvt; |
6899 | | |
6900 | 1.00k | fTagHeaderTree(tvb, pinfo, subtree, start, &tag_no, &tag_info, &lvt); |
6901 | | |
6902 | 1.00k | return offset; |
6903 | 1.00k | } |
6904 | | |
6905 | | static unsigned |
6906 | | fAddress(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
6907 | 1.97k | { |
6908 | 1.97k | uint8_t tag_no, tag_info; |
6909 | 1.97k | uint32_t lvt; |
6910 | 1.97k | unsigned offs; |
6911 | | |
6912 | 1.97k | offset = fUnsignedTag(tvb, pinfo, tree, offset, "network-number"); |
6913 | 1.97k | offs = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
6914 | 1.97k | if (lvt == 0) { |
6915 | 943 | proto_tree_add_item(tree, hf_bacapp_tag_mac_address_broadcast, tvb, offset, offs, ENC_NA); |
6916 | 943 | offset += offs; |
6917 | 943 | } else |
6918 | 1.03k | offset = fMacAddress(tvb, pinfo, tree, offset, "MAC-address: ", lvt); |
6919 | | |
6920 | 1.97k | return offset; |
6921 | 1.97k | } |
6922 | | |
6923 | | static unsigned |
6924 | | fSessionKey(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
6925 | 386 | { |
6926 | 386 | offset = fOctetString(tvb, pinfo, tree, offset, "session key: ", 8); |
6927 | 386 | return fAddress(tvb, pinfo, tree, offset); |
6928 | 386 | } |
6929 | | |
6930 | | static void |
6931 | | format_object_identifier(char *s, uint32_t object_id) |
6932 | 0 | { |
6933 | 0 | uint32_t type = object_id_type(object_id); |
6934 | 0 | const char* abbrev = try_val_to_str(type, BACnetObjectTypeAbbrev); |
6935 | 0 | if (abbrev) { |
6936 | 0 | snprintf(s, ITEM_LABEL_LENGTH, |
6937 | 0 | "%s-%u", abbrev, object_id_instance(object_id)); |
6938 | 0 | } else { |
6939 | 0 | snprintf(s, ITEM_LABEL_LENGTH, |
6940 | 0 | "[%u]-%u", type, object_id_instance(object_id)); |
6941 | 0 | } |
6942 | 0 | } |
6943 | | |
6944 | | static unsigned |
6945 | | fObjectIdentifier(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, int hfid) |
6946 | 32.1k | { |
6947 | 32.1k | uint8_t tag_no, tag_info; |
6948 | 32.1k | uint32_t lvt; |
6949 | 32.1k | unsigned tag_length; |
6950 | 32.1k | proto_tree *subtree; |
6951 | 32.1k | uint32_t object_id; |
6952 | | |
6953 | 32.1k | tag_length = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
6954 | 32.1k | object_id = tvb_get_ntohl(tvb, offset+tag_length); |
6955 | 32.1k | object_type = object_id_type(object_id); |
6956 | 32.1k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, tag_length + 4, |
6957 | 32.1k | ett_bacapp_tag, NULL, "%s: %s, %u", proto_registrar_get_name(hfid), |
6958 | 32.1k | val_to_split_str(pinfo->pool, object_type, |
6959 | 32.1k | 128, |
6960 | 32.1k | BACnetObjectType, |
6961 | 32.1k | ASHRAE_Reserved_Fmt, |
6962 | 32.1k | Vendor_Proprietary_Fmt), |
6963 | 32.1k | object_id_instance(object_id)); |
6964 | | |
6965 | 32.1k | col_append_fstr(pinfo->cinfo, COL_INFO, "%s,%u ", |
6966 | 32.1k | val_to_split_str(pinfo->pool, object_type, |
6967 | 32.1k | 128, |
6968 | 32.1k | BACnetObjectType, |
6969 | 32.1k | ASHRAE_Reserved_Fmt, |
6970 | 32.1k | Vendor_Proprietary_Fmt), |
6971 | 32.1k | object_id_instance(object_id)); |
6972 | | |
6973 | | /* update BACnet Statistics */ |
6974 | 32.1k | updateBacnetInfoValue(BACINFO_OBJECTID, |
6975 | 32.1k | wmem_strdup(pinfo->pool, |
6976 | 32.1k | val_to_split_str(pinfo->pool, object_type, 128, |
6977 | 32.1k | BACnetObjectType, ASHRAE_Reserved_Fmt, |
6978 | 32.1k | Vendor_Proprietary_Fmt))); |
6979 | 32.1k | updateBacnetInfoValue(BACINFO_INSTANCEID, |
6980 | 32.1k | wmem_strdup_printf(pinfo->pool, |
6981 | 32.1k | "Instance ID: %u", |
6982 | 32.1k | object_id_instance(object_id))); |
6983 | | |
6984 | | /* here are the details of how we arrived at the above text */ |
6985 | 32.1k | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
6986 | 32.1k | offset += tag_length; |
6987 | 32.1k | static int * const object_identifier_fields[] = { |
6988 | 32.1k | &hf_bacapp_objectType, |
6989 | 32.1k | &hf_bacapp_instanceNumber, |
6990 | 32.1k | NULL |
6991 | 32.1k | }; |
6992 | 32.1k | proto_tree_add_bitmask_with_flags(subtree, tvb, offset, hfid, |
6993 | 32.1k | ett_bacapp_object_identifier, object_identifier_fields, ENC_BIG_ENDIAN, BMT_NO_APPEND); |
6994 | 32.1k | offset += 4; |
6995 | | |
6996 | 32.1k | return offset; |
6997 | 32.1k | } |
6998 | | |
6999 | | static unsigned |
7000 | | fObjectName(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
7001 | 196 | { |
7002 | 196 | return fCharacterStringBase(tvb, pinfo, tree, offset, "Object Name", false, true); |
7003 | 196 | } |
7004 | | |
7005 | | static unsigned |
7006 | | fRecipient(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
7007 | 4.27k | { |
7008 | 4.27k | uint8_t tag_no, tag_info; |
7009 | 4.27k | uint32_t lvt; |
7010 | | |
7011 | 4.27k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
7012 | 4.27k | if (tag_no < 2) { |
7013 | 1.22k | if (tag_no == 0) { /* device */ |
7014 | 1.13k | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_device_identifier); |
7015 | 1.13k | } |
7016 | 84 | else { /* address */ |
7017 | 84 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
7018 | 84 | offset = fAddress(tvb, pinfo, tree, offset); |
7019 | 84 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
7020 | 84 | } |
7021 | 1.22k | } |
7022 | 4.27k | return offset; |
7023 | 4.27k | } |
7024 | | |
7025 | | static unsigned |
7026 | | fRecipientProcess(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
7027 | 569 | { |
7028 | 569 | unsigned lastoffset = 0; |
7029 | 569 | uint8_t tag_no, tag_info; |
7030 | 569 | uint32_t lvt; |
7031 | 569 | proto_tree *orgtree = tree; |
7032 | 569 | proto_tree *subtree; |
7033 | | |
7034 | | /* beginning of new item - indent and label */ |
7035 | 569 | tree = proto_tree_add_subtree(orgtree, tvb, offset, 1, ett_bacapp_value, NULL, "Recipient Process" ); |
7036 | | |
7037 | 1.07k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
7038 | 1.06k | lastoffset = offset; |
7039 | | |
7040 | 1.06k | switch (fTagNo(tvb, offset)) { |
7041 | 511 | case 0: /* recipient */ |
7042 | 511 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); /* show context open */ |
7043 | 511 | subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_value, NULL, "Recipient"); /* add tree label and indent */ |
7044 | 511 | offset = fRecipient(tvb, pinfo, subtree, offset); |
7045 | 511 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); /* show context close */ |
7046 | 511 | break; |
7047 | 273 | case 1: /* processId */ |
7048 | 273 | offset = fProcessId(tvb, pinfo, tree, offset); |
7049 | 273 | lastoffset = offset; |
7050 | 273 | break; |
7051 | 282 | default: |
7052 | 282 | break; |
7053 | 1.06k | } |
7054 | 1.05k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
7055 | 1.05k | } |
7056 | 559 | return offset; |
7057 | 569 | } |
7058 | | |
7059 | | static unsigned |
7060 | | fCOVSubscription(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
7061 | 64 | { |
7062 | 64 | unsigned lastoffset = 0; |
7063 | 64 | uint8_t tag_no, tag_info; |
7064 | 64 | uint32_t lvt; |
7065 | 64 | proto_tree *subtree; |
7066 | 64 | proto_tree *orgtree = tree; |
7067 | 64 | unsigned itemno = 1; |
7068 | | |
7069 | 822 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
7070 | 820 | lastoffset = offset; |
7071 | 820 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
7072 | 820 | if (tag_is_closing(tag_info) ) { |
7073 | 8 | return offset; |
7074 | 8 | } |
7075 | 812 | switch (tag_no) { |
7076 | | |
7077 | 135 | case 0: /* recipient */ |
7078 | | /* beginning of new item in list */ |
7079 | 135 | tree = proto_tree_add_subtree_format(orgtree, tvb, offset, 1, |
7080 | 135 | ett_bacapp_value, NULL, "Subscription %d",itemno); /* add tree label and indent */ |
7081 | 135 | itemno = itemno + 1; |
7082 | | |
7083 | 135 | subtree = proto_tree_add_subtree(tree, tvb, offset, 1, |
7084 | 135 | ett_bacapp_value, NULL, "Recipient"); /* add tree label and indent */ |
7085 | 135 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* show context open */ |
7086 | 135 | offset = fRecipientProcess(tvb, pinfo, subtree, offset); |
7087 | 135 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* show context close */ |
7088 | 135 | break; |
7089 | 115 | case 1: /* MonitoredPropertyReference */ |
7090 | 115 | subtree = proto_tree_add_subtree(tree, tvb, offset, 1, |
7091 | 115 | ett_bacapp_value, NULL, "Monitored Property Reference"); |
7092 | 115 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
7093 | 115 | offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset); |
7094 | 115 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
7095 | 115 | break; |
7096 | 324 | case 2: /* IssueConfirmedNotifications - boolean */ |
7097 | 324 | offset = fBooleanTag(tvb, pinfo, tree, offset, "Issue Confirmed Notifications: "); |
7098 | 324 | break; |
7099 | 87 | case 3: /* TimeRemaining */ |
7100 | 87 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "Time Remaining: "); |
7101 | 87 | break; |
7102 | 101 | case 4: /* COVIncrement */ |
7103 | 101 | offset = fRealTag(tvb, pinfo, tree, offset, "COV Increment: "); |
7104 | 101 | break; |
7105 | 49 | default: |
7106 | 49 | break; |
7107 | 812 | } |
7108 | 807 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
7109 | 807 | } |
7110 | 51 | return offset; |
7111 | 64 | } |
7112 | | |
7113 | | static unsigned |
7114 | | fAddressBinding(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
7115 | 251 | { |
7116 | 251 | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_device_identifier); |
7117 | 251 | return fAddress(tvb, pinfo, tree, offset); |
7118 | 251 | } |
7119 | | |
7120 | | static unsigned |
7121 | | // NOLINTNEXTLINE(misc-no-recursion) |
7122 | | fActionCommand(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, uint8_t tag_match) |
7123 | 799 | { |
7124 | 799 | unsigned lastoffset = 0, len; |
7125 | 799 | uint8_t tag_no, tag_info; |
7126 | 799 | uint32_t lvt; |
7127 | 799 | proto_tree *subtree = tree; |
7128 | | |
7129 | | /* set the optional global properties to indicate not-used */ |
7130 | 799 | propertyArrayIndex = -1; |
7131 | 8.00k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
7132 | 7.91k | lastoffset = offset; |
7133 | 7.91k | len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
7134 | 7.91k | if (tag_is_closing(tag_info) ) { |
7135 | 933 | if (tag_no == tag_match) { |
7136 | 63 | return offset; |
7137 | 63 | } |
7138 | 870 | offset += len; |
7139 | 870 | subtree = tree; |
7140 | 870 | continue; |
7141 | 933 | } |
7142 | 6.98k | switch (tag_no) { |
7143 | | |
7144 | 2.27k | case 0: /* deviceIdentifier */ |
7145 | 2.27k | offset = fObjectIdentifier(tvb, pinfo, subtree, offset, hf_bacapp_device_identifier); |
7146 | 2.27k | break; |
7147 | 390 | case 1: /* objectIdentifier */ |
7148 | 390 | offset = fObjectIdentifier(tvb, pinfo, subtree, offset, hf_bacapp_object_identifier); |
7149 | 390 | break; |
7150 | 572 | case 2: /* propertyIdentifier */ |
7151 | 572 | offset = fPropertyIdentifier(tvb, pinfo, subtree, offset); |
7152 | 572 | break; |
7153 | 598 | case 3: /* propertyArrayIndex */ |
7154 | 598 | offset = fPropertyArrayIndex(tvb, pinfo, subtree, offset); |
7155 | 598 | break; |
7156 | 454 | case 4: /* propertyValue */ |
7157 | 454 | offset = fPropertyValue(tvb, pinfo, subtree, offset, tag_info); |
7158 | 454 | break; |
7159 | 603 | case 5: /* priority */ |
7160 | 603 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "Priority: "); |
7161 | 603 | break; |
7162 | 506 | case 6: /* postDelay */ |
7163 | 506 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "Post Delay: "); |
7164 | 506 | break; |
7165 | 613 | case 7: /* quitOnFailure */ |
7166 | 613 | offset = fBooleanTag(tvb, pinfo, subtree, offset, |
7167 | 613 | "Quit On Failure: "); |
7168 | 613 | break; |
7169 | 472 | case 8: /* writeSuccessful */ |
7170 | 472 | offset = fBooleanTag(tvb, pinfo, subtree, offset, |
7171 | 472 | "Write Successful: "); |
7172 | 472 | break; |
7173 | 484 | default: |
7174 | 484 | return offset; |
7175 | 6.98k | } |
7176 | 6.39k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
7177 | 6.39k | } |
7178 | 145 | return offset; |
7179 | 799 | } |
7180 | | |
7181 | | /* BACnetActionList ::= SEQUENCE{ |
7182 | | action [0] SEQUENCE OF BACnetActionCommand |
7183 | | } |
7184 | | */ |
7185 | | static unsigned |
7186 | | // NOLINTNEXTLINE(misc-no-recursion) |
7187 | | fActionList(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
7188 | 865 | { |
7189 | 865 | unsigned lastoffset = 0, len; |
7190 | 865 | uint8_t tag_no, tag_info; |
7191 | 865 | uint32_t lvt; |
7192 | 865 | proto_tree *subtree = tree; |
7193 | | |
7194 | 3.00k | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
7195 | 2.91k | lastoffset = offset; |
7196 | 2.91k | len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
7197 | 2.91k | if (tag_is_closing(tag_info)) { |
7198 | 409 | if ( tag_no != 0 ) /* don't eat the closing property tag, just return */ |
7199 | 17 | return offset; |
7200 | | /* print closing tag of action list too */ |
7201 | 392 | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
7202 | 392 | subtree = tree; |
7203 | 392 | offset += len; |
7204 | 392 | continue; |
7205 | 409 | } |
7206 | 2.50k | if (tag_is_opening(tag_info)) { |
7207 | 1.05k | subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_tag, NULL, "Action List"); |
7208 | 1.05k | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, |
7209 | 1.05k | &tag_no, &tag_info, &lvt); |
7210 | 1.05k | } |
7211 | 2.50k | switch (tag_no) { |
7212 | 799 | case 0: /* BACnetActionCommand */ |
7213 | 799 | offset = fActionCommand(tvb, pinfo, subtree, offset, tag_no); |
7214 | 799 | break; |
7215 | 1.70k | default: |
7216 | 1.70k | break; |
7217 | 2.50k | } |
7218 | 2.39k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
7219 | 2.39k | } |
7220 | 741 | return offset; |
7221 | 865 | } |
7222 | | |
7223 | | static unsigned |
7224 | | // NOLINTNEXTLINE(misc-no-recursion) |
7225 | | fPropertyAccessResult(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
7226 | 842 | { |
7227 | 842 | unsigned lastoffset = 0; |
7228 | 842 | uint8_t tag_no, tag_info; |
7229 | 842 | uint32_t lvt; |
7230 | 842 | uint32_t save_object_type; |
7231 | 842 | uint32_t save_inner_object_type; |
7232 | 842 | int32_t save_propertyIdentifier; |
7233 | | |
7234 | | /* save the external entry data because it might get overwritten here */ |
7235 | 842 | save_object_type = object_type; |
7236 | 842 | save_propertyIdentifier = propertyIdentifier; |
7237 | | |
7238 | | /* inner object type might get overwritten by device id */ |
7239 | 842 | save_inner_object_type = object_type; |
7240 | | |
7241 | 2.20k | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
7242 | 2.02k | lastoffset = offset; |
7243 | 2.02k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
7244 | 2.02k | if (tag_is_closing(tag_info)) { |
7245 | 150 | break; |
7246 | 150 | } |
7247 | | |
7248 | 1.87k | switch (tag_no) { |
7249 | 461 | case 0: /* objectIdentifier */ |
7250 | 461 | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_object_identifier); |
7251 | | /* save the local object type because device id might overwrite it */ |
7252 | 461 | save_inner_object_type = object_type; |
7253 | 461 | break; |
7254 | 125 | case 1: /* propertyIdentifier */ |
7255 | 125 | offset = fPropertyIdentifier(tvb, pinfo, tree, offset); |
7256 | 125 | break; |
7257 | 205 | case 2: /* propertyArrayIndex */ |
7258 | 205 | offset = fPropertyArrayIndex(tvb, pinfo, tree, offset); |
7259 | 205 | break; |
7260 | 87 | case 3: /* deviceIdentifier */ |
7261 | 87 | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_device_identifier); |
7262 | | /* restore the inner object type to decode the right property value */ |
7263 | 87 | object_type = save_inner_object_type; |
7264 | 87 | break; |
7265 | 506 | case 4: /* propertyValue */ |
7266 | 506 | offset = fPropertyValue(tvb, pinfo, tree, offset, tag_info); |
7267 | | /* restore the external values for next loop */ |
7268 | 506 | object_type = save_object_type; |
7269 | 506 | propertyIdentifier = save_propertyIdentifier; |
7270 | 506 | break; |
7271 | 53 | case 5: /* propertyAccessError */ |
7272 | 53 | if (tag_is_opening(tag_info)) { |
7273 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
7274 | 0 | offset = fError(tvb, pinfo, tree, offset); |
7275 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
7276 | 0 | } |
7277 | 53 | else { |
7278 | 53 | expert_add_info(pinfo, tree, &ei_bacapp_bad_tag); |
7279 | 53 | } |
7280 | | /* restore the external values for next loop */ |
7281 | 53 | object_type = save_object_type; |
7282 | 53 | propertyIdentifier = save_propertyIdentifier; |
7283 | 53 | break; |
7284 | 434 | default: |
7285 | 434 | break; |
7286 | 1.87k | } |
7287 | | |
7288 | 1.86k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
7289 | 1.86k | } |
7290 | | |
7291 | | /* restore the external values for next decoding */ |
7292 | 840 | object_type = save_object_type; |
7293 | 840 | propertyIdentifier = save_propertyIdentifier; |
7294 | 840 | return offset; |
7295 | 842 | } |
7296 | | |
7297 | | static unsigned |
7298 | | fPropertyIdentifier(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
7299 | 10.7k | { |
7300 | 10.7k | uint8_t tag_no, tag_info; |
7301 | 10.7k | uint32_t lvt; |
7302 | 10.7k | unsigned tag_len; |
7303 | 10.7k | proto_tree *subtree; |
7304 | 10.7k | static const char *label = "Property Identifier"; |
7305 | | |
7306 | 10.7k | propertyIdentifier = 0; /* global Variable */ |
7307 | 10.7k | tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
7308 | | /* can we decode this value? */ |
7309 | 10.7k | if (fUnsigned32(tvb, offset+tag_len, lvt, (uint32_t *)&propertyIdentifier)) { |
7310 | 8.58k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, |
7311 | 8.58k | ett_bacapp_tag, NULL, |
7312 | 8.58k | "%s: %s (%u)", label, |
7313 | 8.58k | val_to_split_str(pinfo->pool, propertyIdentifier, 512, |
7314 | 8.58k | BACnetPropertyIdentifier, |
7315 | 8.58k | ASHRAE_Reserved_Fmt, |
7316 | 8.58k | Vendor_Proprietary_Fmt), propertyIdentifier); |
7317 | 8.58k | col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", |
7318 | 8.58k | val_to_split_str(pinfo->pool, propertyIdentifier, 512, |
7319 | 8.58k | BACnetPropertyIdentifier, |
7320 | 8.58k | ASHRAE_Reserved_Fmt, |
7321 | 8.58k | Vendor_Proprietary_Fmt)); |
7322 | 8.58k | } else { |
7323 | | /* property identifiers cannot be larger than 22-bits */ |
7324 | 2.12k | return offset; |
7325 | 2.12k | } |
7326 | | |
7327 | 8.58k | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
7328 | 8.58k | proto_tree_add_item(subtree, hf_BACnetPropertyIdentifier, tvb, |
7329 | 8.58k | offset+tag_len, lvt, ENC_BIG_ENDIAN); |
7330 | | |
7331 | 8.58k | return offset+tag_len+lvt; |
7332 | 10.7k | } |
7333 | | |
7334 | | static unsigned |
7335 | | fPropertyArrayIndex(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
7336 | 2.72k | { |
7337 | 2.72k | uint8_t tag_no, tag_info; |
7338 | 2.72k | uint32_t lvt; |
7339 | 2.72k | unsigned tag_len; |
7340 | 2.72k | proto_tree *subtree; |
7341 | | |
7342 | 2.72k | tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
7343 | 2.72k | if (fUnsigned32(tvb, offset + tag_len, lvt, (uint32_t *)&propertyArrayIndex)) |
7344 | 1.68k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, |
7345 | 1.68k | ett_bacapp_tag, NULL, "property Array Index (Unsigned) %u", propertyArrayIndex); |
7346 | 1.04k | else |
7347 | 1.04k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, |
7348 | 1.04k | ett_bacapp_tag, NULL, "property Array Index - %u octets (Unsigned)", lvt); |
7349 | 2.72k | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
7350 | | |
7351 | 2.72k | return offset+tag_len+lvt; |
7352 | 2.72k | } |
7353 | | |
7354 | | static unsigned |
7355 | | fChannelValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label) |
7356 | 9.56k | { |
7357 | 9.56k | uint8_t tag_no, tag_info; |
7358 | 9.56k | uint32_t lvt; |
7359 | | |
7360 | 9.56k | if (tvb_reported_length_remaining(tvb, offset) > 0) { |
7361 | 9.56k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
7362 | 9.56k | if (tag_is_opening(tag_info) && tag_no == 0) { |
7363 | 188 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
7364 | 188 | offset = fLightingCommand(tvb, pinfo, tree, offset, "lighting-command: "); |
7365 | 188 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
7366 | 9.37k | } else if (tag_is_opening(tag_info) && tag_no == 1) { |
7367 | 124 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
7368 | 124 | offset = fXyColor(tvb, pinfo, tree, offset, "xy-color: "); |
7369 | 124 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
7370 | 9.25k | } else if (tag_is_opening(tag_info) && tag_no == 2) { |
7371 | 265 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
7372 | 265 | offset = fColorCommand(tvb, pinfo, tree, offset, "color-command: "); |
7373 | 265 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
7374 | 8.98k | } else { |
7375 | 8.98k | if (tag_info) { |
7376 | 2.40k | offset = fContextTaggedValue(tvb, pinfo, tree, offset, label); |
7377 | 6.58k | } else { |
7378 | 6.58k | offset = fApplicationTypes(tvb, pinfo, tree, offset, label); |
7379 | 6.58k | } |
7380 | 8.98k | } |
7381 | 9.56k | } |
7382 | | |
7383 | 9.56k | return offset; |
7384 | 9.56k | } |
7385 | | |
7386 | | static unsigned |
7387 | | fCharacterString(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label) |
7388 | 5.97k | { |
7389 | 5.97k | return fCharacterStringBase(tvb, pinfo, tree, offset, label, false, false); |
7390 | 5.97k | } |
7391 | | |
7392 | | static unsigned |
7393 | | fCharacterStringBase(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label, bool present_val_dissect, bool object_name_dissect) |
7394 | 6.62k | { |
7395 | 6.62k | uint8_t tag_no, tag_info, character_set; |
7396 | 6.62k | uint32_t lvt, l; |
7397 | 6.62k | unsigned offs; |
7398 | 6.62k | const char *coding; |
7399 | 6.62k | uint8_t *out; |
7400 | 6.62k | proto_tree *subtree; |
7401 | 6.62k | unsigned start = offset; |
7402 | | |
7403 | 6.62k | if (tvb_reported_length_remaining(tvb, offset) > 0) { |
7404 | | |
7405 | 6.61k | offs = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
7406 | 6.61k | offset += offs; |
7407 | | |
7408 | 6.61k | character_set = tvb_get_uint8(tvb, offset); |
7409 | 6.61k | offset++; |
7410 | 6.61k | lvt--; |
7411 | | |
7412 | | /* Account for code page if DBCS */ |
7413 | 6.61k | if (character_set == IBM_MS_DBCS) { |
7414 | 92 | offset += 2; |
7415 | 92 | lvt -= 2; |
7416 | 92 | } |
7417 | | |
7418 | 6.66k | do { |
7419 | 6.66k | l = MIN(lvt, 256); |
7420 | | /* |
7421 | | * XXX - are we guaranteed that these encoding |
7422 | | * names correspond, on *all* platforms with |
7423 | | * iconv(), to the encodings we want? |
7424 | | * |
7425 | | * Not necessarily. These specify "character sets" but |
7426 | | * not the encodings. IBM/MS DBCS specifies that it uses |
7427 | | * some IBM or MS double byte character set, but does not |
7428 | | * specify the code page - there was a proposal to explicitly |
7429 | | * add the code page, but that was apparently withdrawn in favor |
7430 | | * of just deprecating using DBCS, as it never got past a draft |
7431 | | * (One problem could be that IBM and MS code pages with the |
7432 | | * same number are slightly different, and then there's non |
7433 | | * IBM/MS unofficial ones that got used, sometimes conflicting |
7434 | | * numbers.) Even if we assume that they certainly mean one |
7435 | | * of the DBCS and not just any non ISO-8859-1 code page, there's |
7436 | | * all four types of CJK to choose from. - |
7437 | | * http://www.bacnet.org/Addenda/Add-135-2004k-PPR1-chair-approved.pdf |
7438 | | * JIS C 6226 (now JIS X 0208) |
7439 | | * http://www.bacnet.org/Addenda/Add-135-2008k.pdf |
7440 | | * is a character set, which are supported by several different |
7441 | | * encodings, the main types being ISO-2022-JP (JIS X 0202, |
7442 | | * a 7 bit encoding), Shift-JIS (most common), and EUC-JP (UNIX). |
7443 | | * It is unclear which encoding this refers to. |
7444 | | * |
7445 | | * If not (and perhaps even if so), we should |
7446 | | * perhaps have our own iconv() implementation, |
7447 | | * with a different name, so that we control the |
7448 | | * encodings it supports and the names of those |
7449 | | * encodings. |
7450 | | * |
7451 | | * We should also handle that in the general |
7452 | | * string handling code, rather than making it |
7453 | | * specific to the BACAPP dissector, as many |
7454 | | * other dissectors need to handle various |
7455 | | * character encodings. |
7456 | | */ |
7457 | | /** this decoding may be not correct for multi-byte characters, Lka */ |
7458 | 6.66k | switch (character_set) { |
7459 | 415 | case ANSI_X3_4: |
7460 | 415 | out = tvb_get_string_enc(pinfo->pool, tvb, offset, l, ENC_UTF_8); |
7461 | 415 | coding = "UTF-8"; |
7462 | 415 | break; |
7463 | 92 | case IBM_MS_DBCS: |
7464 | 92 | out = tvb_get_string_enc(pinfo->pool, tvb, offset, l, ENC_ASCII); |
7465 | 92 | coding = "IBM MS DBCS"; |
7466 | 92 | break; |
7467 | 125 | case JIS_C_6226: |
7468 | 125 | out = tvb_get_string_enc(pinfo->pool, tvb, offset, l, ENC_ASCII); |
7469 | 125 | coding = "JIS C 6226"; |
7470 | 125 | break; |
7471 | 139 | case ISO_10646_UCS4: |
7472 | 139 | out = tvb_get_string_enc(pinfo->pool, tvb, offset, l, ENC_UCS_4|ENC_BIG_ENDIAN); |
7473 | 139 | coding = "ISO 10646 UCS-4"; |
7474 | 139 | break; |
7475 | 66 | case ISO_10646_UCS2: |
7476 | 66 | out = tvb_get_string_enc(pinfo->pool, tvb, offset, l, ENC_UCS_2|ENC_BIG_ENDIAN); |
7477 | 66 | coding = "ISO 10646 UCS-2"; |
7478 | 66 | break; |
7479 | 56 | case ISO_8859_1: |
7480 | 56 | out = tvb_get_string_enc(pinfo->pool, tvb, offset, l, ENC_ISO_8859_1); |
7481 | 56 | coding = "ISO 8859-1"; |
7482 | 56 | break; |
7483 | 5.74k | default: |
7484 | | /* Assume this is some form of extended ASCII, with one-byte code points for ASCII characters */ |
7485 | 5.74k | out = tvb_get_string_enc(pinfo->pool, tvb, offset, l, ENC_ASCII); |
7486 | 5.74k | coding = "unknown"; |
7487 | 5.74k | break; |
7488 | 6.66k | } |
7489 | | |
7490 | 6.40k | if (present_val_dissect) { |
7491 | 439 | subtree = proto_tree_add_subtree(tree, tvb, offset, l, ett_bacapp_tag, NULL, "present-value"); |
7492 | 439 | proto_tree_add_string(subtree, hf_bacapp_present_value_char_string, tvb, offset, l, (const char*) out); |
7493 | 5.96k | } else if (object_name_dissect) { |
7494 | 182 | subtree = proto_tree_add_subtree(tree, tvb, offset, l, ett_bacapp_tag, NULL, label); |
7495 | 182 | proto_tree_add_string(subtree, hf_bacapp_object_name, tvb, offset, l, (const char*) out); |
7496 | 5.77k | } else { |
7497 | 5.77k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, l, ett_bacapp_tag, NULL, |
7498 | 5.77k | "%s%s '%s'", label, coding, out); |
7499 | 5.77k | } |
7500 | | |
7501 | 6.40k | lvt -= l; |
7502 | 6.40k | offset += l; |
7503 | 6.40k | } while (lvt > 0); |
7504 | | |
7505 | 6.35k | fTagHeaderTree(tvb, pinfo, subtree, start, &tag_no, &tag_info, &lvt); |
7506 | 6.35k | proto_tree_add_item(subtree, hf_BACnetCharacterSet, tvb, start+offs, 1, ENC_BIG_ENDIAN); |
7507 | | |
7508 | 6.35k | if (character_set == IBM_MS_DBCS) { |
7509 | 79 | proto_tree_add_item(subtree, hf_BACnetCodePage, tvb, start+offs+1, 2, ENC_BIG_ENDIAN); |
7510 | 79 | } |
7511 | | /* XXX - put the string value here */ |
7512 | 6.35k | } |
7513 | 6.36k | return offset; |
7514 | 6.62k | } |
7515 | | |
7516 | | static unsigned |
7517 | | fBitStringTagVS(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label, |
7518 | | const value_string *src) |
7519 | 6.39k | { |
7520 | 6.39k | return fBitStringTagVSBase(tvb, pinfo, tree, offset, label, src, false); |
7521 | 6.39k | } |
7522 | | |
7523 | | static unsigned |
7524 | | fBitStringTagVSBase(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label, |
7525 | | const value_string *src, bool present_val_dissect) |
7526 | 7.14k | { |
7527 | 7.14k | uint8_t tag_no, tag_info, tmp; |
7528 | 7.14k | int j, unused, skip; |
7529 | 7.14k | unsigned start = offset; |
7530 | 7.14k | unsigned offs; |
7531 | 7.14k | uint32_t lvt, i, numberOfBytes; |
7532 | 7.14k | char bf_arr[256 + 1]; |
7533 | 7.14k | proto_tree *subtree = tree; |
7534 | | |
7535 | 7.14k | offs = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
7536 | 7.14k | numberOfBytes = lvt-1; /* Ignore byte for unused bit count */ |
7537 | 7.14k | offset += offs; |
7538 | 7.14k | unused = tvb_get_uint8(tvb, offset); /* get the unused Bits */ |
7539 | | |
7540 | 7.14k | memset(bf_arr, 0, sizeof(bf_arr)); |
7541 | 7.14k | skip = 0; |
7542 | 40.7k | for (i = 0; i < numberOfBytes; i++) { |
7543 | 33.5k | tmp = tvb_get_uint8(tvb, (offset)+i + 1); |
7544 | 33.5k | if (i == numberOfBytes - 1) { skip = unused; } |
7545 | 266k | for (j = 0; j < 8 - skip; j++) { |
7546 | 233k | bf_arr[MIN(sizeof(bf_arr) - 2, (i * 8) + j)] = tmp & (1 << (7 - j)) ? 'T' : 'F'; |
7547 | 233k | } |
7548 | 33.5k | } |
7549 | | |
7550 | 7.14k | if (!present_val_dissect) { |
7551 | 6.12k | subtree = proto_tree_add_subtree_format(tree, tvb, start, offs+lvt, |
7552 | 6.12k | ett_bacapp_tag, NULL, |
7553 | 6.12k | "%s(Bit String) (%s)", label, bf_arr); |
7554 | 6.12k | } else { |
7555 | 1.02k | subtree = proto_tree_add_subtree_format(tree, tvb, start, offs+lvt, |
7556 | 1.02k | ett_bacapp_tag, NULL, |
7557 | 1.02k | "present-value (%s)", bf_arr); |
7558 | 1.02k | } |
7559 | | |
7560 | 7.14k | fTagHeaderTree(tvb, pinfo, subtree, start, &tag_no, &tag_info, &lvt); |
7561 | 7.14k | proto_tree_add_item(subtree, hf_bacapp_unused_bits, tvb, offset, 1, ENC_NA); |
7562 | 7.14k | memset(bf_arr, 0, sizeof(bf_arr)); |
7563 | 7.14k | skip = 0; |
7564 | 24.9k | for (i = 0; i < numberOfBytes; i++) { |
7565 | 17.7k | tmp = tvb_get_uint8(tvb, (offset)+i+1); |
7566 | 17.7k | if (i == numberOfBytes-1) { skip = unused; } |
7567 | 126k | for (j = 0; j < 8-skip; j++) { |
7568 | 108k | if (src != NULL) { |
7569 | 50.0k | proto_tree_add_boolean_format(subtree, hf_bacapp_bit, tvb, offset+i+1, 1, |
7570 | 50.0k | (tmp & (1 << (7 - j))), "%s = %s", |
7571 | 50.0k | val_to_str(pinfo->pool, (unsigned) (i*8 +j), src, ASHRAE_Reserved_Fmt), |
7572 | 50.0k | (tmp & (1 << (7 - j))) ? "TRUE" : "FALSE"); |
7573 | 58.7k | } else { |
7574 | 58.7k | bf_arr[MIN(255, (i*8)+j)] = tmp & (1 << (7 - j)) ? '1' : '0'; |
7575 | 58.7k | } |
7576 | 108k | } |
7577 | 17.7k | } |
7578 | | |
7579 | 7.14k | if (src == NULL) { |
7580 | 3.22k | bf_arr[MIN(255, numberOfBytes*8-unused)] = 0; |
7581 | 3.22k | proto_tree_add_bytes_format(subtree, hf_bacapp_complete_bitstring, tvb, offset, lvt, NULL, "B'%s'", bf_arr); |
7582 | 3.22k | } |
7583 | | |
7584 | 7.14k | offset += lvt; |
7585 | | |
7586 | 7.14k | return offset; |
7587 | 7.14k | } |
7588 | | |
7589 | | static unsigned |
7590 | | fBitStringTag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label) |
7591 | 1.94k | { |
7592 | 1.94k | return fBitStringTagVS(tvb, pinfo, tree, offset, label, NULL); |
7593 | 1.94k | } |
7594 | | |
7595 | | /* handles generic application types, as well as enumerated and enumerations |
7596 | | with reserved and proprietary ranges (split) */ |
7597 | | static unsigned |
7598 | | fApplicationTypesEnumeratedSplit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, |
7599 | | const char *label, const value_string *src, uint32_t split_val) |
7600 | 48.1k | { |
7601 | 48.1k | uint8_t tag_no, tag_info; |
7602 | 48.1k | uint32_t lvt; |
7603 | 48.1k | unsigned tag_len; |
7604 | | |
7605 | 48.1k | if (tvb_reported_length_remaining(tvb, offset) > 0) { |
7606 | 48.0k | tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
7607 | 48.0k | if (!tag_is_context_specific(tag_info)) { |
7608 | 42.6k | switch (tag_no) { |
7609 | 23.8k | case 0: /** NULL 20.2.2 */ |
7610 | 23.8k | offset = fNullTag(tvb, pinfo, tree, offset, label); |
7611 | 23.8k | break; |
7612 | 3.20k | case 1: /** BOOLEAN 20.2.3 */ |
7613 | 3.20k | offset = fBooleanTag(tvb, pinfo, tree, offset, label); |
7614 | 3.20k | break; |
7615 | 2.01k | case 2: /** Unsigned Integer 20.2.4 */ |
7616 | 2.01k | offset = fUnsignedTag(tvb, pinfo, tree, offset, label); |
7617 | 2.01k | break; |
7618 | 2.09k | case 3: /** Signed Integer 20.2.5 */ |
7619 | 2.09k | offset = fSignedTag(tvb, pinfo, tree, offset, label); |
7620 | 2.09k | break; |
7621 | 956 | case 4: /** Real 20.2.6 */ |
7622 | 956 | offset = fRealTag(tvb, pinfo, tree, offset, label); |
7623 | 956 | break; |
7624 | 509 | case 5: /** Double 20.2.7 */ |
7625 | 509 | offset = fDoubleTag(tvb, pinfo, tree, offset, label); |
7626 | 509 | break; |
7627 | 1.92k | case 6: /** Octet String 20.2.8 */ |
7628 | 1.92k | offset = fOctetString(tvb, pinfo, tree, offset, label, lvt); |
7629 | 1.92k | break; |
7630 | 679 | case 7: /** Character String 20.2.9 */ |
7631 | 679 | offset = fCharacterString(tvb, pinfo, tree, offset, label); |
7632 | 679 | break; |
7633 | 953 | case 8: /** Bit String 20.2.10 */ |
7634 | 953 | offset = fBitStringTagVS(tvb, pinfo, tree, offset, label, src); |
7635 | 953 | break; |
7636 | 1.06k | case 9: /** Enumerated 20.2.11 */ |
7637 | 1.06k | offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset, label, src, split_val); |
7638 | 1.06k | break; |
7639 | 952 | case 10: /** Date 20.2.12 */ |
7640 | 952 | offset = fDate(tvb, pinfo, tree, offset, label); |
7641 | 952 | break; |
7642 | 1.03k | case 11: /** Time 20.2.13 */ |
7643 | 1.03k | offset = fTime(tvb, pinfo, tree, offset, label); |
7644 | 1.03k | break; |
7645 | 874 | case 12: /** BACnetObjectIdentifier 20.2.14 */ |
7646 | 874 | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_object_identifier); |
7647 | 874 | break; |
7648 | 972 | case 13: /* reserved for ASHRAE */ |
7649 | 2.25k | case 14: |
7650 | 2.27k | case 15: |
7651 | 2.27k | proto_tree_add_bytes_format(tree, hf_bacapp_reserved_ashrea, tvb, offset, lvt+tag_len, NULL, "%s'reserved for ASHRAE'", label); |
7652 | 2.27k | offset += lvt + tag_len; |
7653 | 2.27k | break; |
7654 | 221 | default: |
7655 | 221 | break; |
7656 | 42.6k | } |
7657 | 42.6k | } |
7658 | 48.0k | } |
7659 | 47.8k | return offset; |
7660 | 48.1k | } |
7661 | | |
7662 | | static unsigned |
7663 | | fShedLevel(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
7664 | 62 | { |
7665 | 62 | unsigned lastoffset = 0; |
7666 | | |
7667 | 654 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
7668 | 651 | lastoffset = offset; |
7669 | | |
7670 | 651 | switch (fTagNo(tvb, offset)) { |
7671 | 334 | case 0: /* percent */ |
7672 | 334 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "shed percent: "); |
7673 | 334 | break; |
7674 | 166 | case 1: /* level */ |
7675 | 166 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "shed level: "); |
7676 | 166 | break; |
7677 | 95 | case 2: /* amount */ |
7678 | 95 | offset = fRealTag(tvb, pinfo, tree, offset, "shed amount: "); |
7679 | 95 | break; |
7680 | 56 | default: |
7681 | 56 | return offset; |
7682 | 651 | } |
7683 | 592 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
7684 | 592 | } |
7685 | 3 | return offset; |
7686 | 62 | } |
7687 | | |
7688 | | static unsigned |
7689 | | fApplicationTypesEnumerated(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, |
7690 | | const char *label, const value_string *vs) |
7691 | 13.3k | { |
7692 | 13.3k | return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, vs, 0); |
7693 | 13.3k | } |
7694 | | |
7695 | | static unsigned |
7696 | | fApplicationTypes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, |
7697 | | const char *label) |
7698 | 33.2k | { |
7699 | 33.2k | return fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, label, NULL, 0); |
7700 | 33.2k | } |
7701 | | |
7702 | | static unsigned |
7703 | | fContextTaggedValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label) |
7704 | 8.96k | { |
7705 | 8.96k | uint8_t tag_no, tag_info; |
7706 | 8.96k | uint32_t lvt; |
7707 | 8.96k | unsigned tag_len; |
7708 | 8.96k | proto_tree *subtree; |
7709 | 8.96k | int tvb_len; |
7710 | | |
7711 | 8.96k | (void)label; |
7712 | 8.96k | tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
7713 | | /* cap the the suggested length in case of bad data */ |
7714 | 8.96k | tvb_len = tvb_reported_length_remaining(tvb, offset+tag_len); |
7715 | 8.96k | if ((tvb_len >= 0) && ((uint32_t)tvb_len < lvt)) { |
7716 | 79 | lvt = tvb_len; |
7717 | 79 | } |
7718 | 8.96k | subtree = proto_tree_add_subtree_format(tree, tvb, offset+tag_len, lvt, |
7719 | 8.96k | ett_bacapp_tag, NULL, "Context Value (as %u DATA octets)", lvt); |
7720 | | |
7721 | 8.96k | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
7722 | | |
7723 | 8.96k | return offset + tag_len + lvt; |
7724 | 8.96k | } |
7725 | | /* |
7726 | | BACnetPrescale ::= SEQUENCE { |
7727 | | multiplier [0] Unsigned, |
7728 | | moduloDivide [1] Unsigned |
7729 | | } |
7730 | | */ |
7731 | | static unsigned |
7732 | | fPrescale(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
7733 | 46 | { |
7734 | 46 | uint8_t tag_no, tag_info; |
7735 | 46 | uint32_t lvt; |
7736 | 46 | unsigned lastoffset = 0; |
7737 | | |
7738 | 296 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
7739 | 296 | lastoffset = offset; |
7740 | 296 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
7741 | 296 | if (tag_is_closing(tag_info) ) { |
7742 | 4 | return offset; |
7743 | 4 | } |
7744 | 292 | switch (tag_no) { |
7745 | 190 | case 0: /* multiplier */ |
7746 | 190 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "Multiplier: "); |
7747 | 190 | break; |
7748 | 61 | case 1: /* moduloDivide */ |
7749 | 61 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "Modulo Divide: "); |
7750 | 61 | break; |
7751 | 41 | default: |
7752 | 41 | return offset; |
7753 | 292 | } |
7754 | 250 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
7755 | 250 | } |
7756 | 0 | return offset; |
7757 | | |
7758 | 46 | } |
7759 | | /* |
7760 | | BACnetScale ::= CHOICE { |
7761 | | floatScale [0] REAL, |
7762 | | integerScale [1] INTEGER |
7763 | | } |
7764 | | */ |
7765 | | static unsigned |
7766 | | fScale(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
7767 | 40 | { |
7768 | 40 | uint8_t tag_no, tag_info; |
7769 | 40 | uint32_t lvt; |
7770 | 40 | unsigned lastoffset = 0; |
7771 | | |
7772 | 95 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
7773 | 92 | lastoffset = offset; |
7774 | 92 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
7775 | 92 | if (tag_is_closing(tag_info) ) { |
7776 | 1 | return offset; |
7777 | 1 | } |
7778 | 91 | switch (tag_no) { |
7779 | 49 | case 0: /* floatScale */ |
7780 | 49 | offset = fRealTag(tvb, pinfo, tree, offset, "Float Scale: "); |
7781 | 49 | break; |
7782 | 8 | case 1: /* integerScale */ |
7783 | 8 | offset = fSignedTag(tvb, pinfo, tree, offset, "Integer Scale: "); |
7784 | 8 | break; |
7785 | 34 | default: |
7786 | 34 | return offset; |
7787 | 91 | } |
7788 | 55 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
7789 | 55 | } |
7790 | 3 | return offset; |
7791 | 40 | } |
7792 | | /* |
7793 | | BACnetAccumulatorRecord ::= SEQUENCE { |
7794 | | timestamp [0] BACnetDateTime, |
7795 | | presentValue [1] Unsigned, |
7796 | | accumulatedValue [2] Unsigned, |
7797 | | accumulatortStatus [3] ENUMERATED { |
7798 | | normal (0), |
7799 | | starting (1), |
7800 | | recovered (2), |
7801 | | abnormal (3), |
7802 | | failed (4) |
7803 | | } |
7804 | | } |
7805 | | */ |
7806 | | static unsigned |
7807 | | fLoggingRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
7808 | 185 | { |
7809 | 185 | uint8_t tag_no, tag_info; |
7810 | 185 | uint32_t lvt; |
7811 | 185 | unsigned lastoffset = 0; |
7812 | | |
7813 | 883 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
7814 | 880 | lastoffset = offset; |
7815 | 880 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
7816 | 880 | if (tag_is_closing(tag_info) ) { |
7817 | 7 | return offset; |
7818 | 7 | } |
7819 | 873 | switch (tag_no) { |
7820 | 405 | case 0: /* timestamp */ |
7821 | 405 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
7822 | 405 | offset = fDateTime(tvb, pinfo, tree, offset, "Timestamp: "); |
7823 | 405 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
7824 | 405 | break; |
7825 | 149 | case 1: /* presentValue */ |
7826 | 149 | offset = fPresentValue(tvb, pinfo, tree, offset, NULL, 0, BACAPP_PRESENT_VALUE_UNSIGNED); |
7827 | 149 | break; |
7828 | 107 | case 2: /* accumulatedValue */ |
7829 | 107 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "Accumulated Value: "); |
7830 | 107 | break; |
7831 | 40 | case 3: /* accumulatorStatus */ |
7832 | 40 | offset = fEnumeratedTag(tvb, pinfo, tree, offset, "Accumulator Status: ", BACnetAccumulatorStatus); |
7833 | 40 | break; |
7834 | 172 | default: |
7835 | 172 | return offset; |
7836 | 873 | } |
7837 | 698 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
7838 | 698 | } |
7839 | 3 | return offset; |
7840 | 185 | } |
7841 | | |
7842 | | /* |
7843 | | SEQ OF Any enumeration (current usage is SEQ OF BACnetDoorAlarmState |
7844 | | */ |
7845 | | static unsigned |
7846 | | fSequenceOfEnums(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label, const value_string *vs) |
7847 | 110 | { |
7848 | 110 | uint8_t tag_no, tag_info; |
7849 | 110 | uint32_t lvt; |
7850 | 110 | unsigned lastoffset = 0; |
7851 | | |
7852 | 503 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
7853 | 496 | lastoffset = offset; |
7854 | 496 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
7855 | 496 | if (tag_is_closing(tag_info) ) { |
7856 | 5 | return offset; |
7857 | 5 | } |
7858 | 491 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, label, vs); |
7859 | 491 | if ( offset <= lastoffset ) break; |
7860 | 491 | } |
7861 | 105 | return offset; |
7862 | 110 | } |
7863 | | |
7864 | | /* |
7865 | | SEQ OF BACnetDeviceObjectReference (accessed as an array) |
7866 | | } |
7867 | | */ |
7868 | | static unsigned |
7869 | | fDoorMembers(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
7870 | 52 | { |
7871 | 52 | uint8_t tag_no, tag_info; |
7872 | 52 | uint32_t lvt; |
7873 | 52 | unsigned lastoffset = 0; |
7874 | | |
7875 | 69 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
7876 | 66 | lastoffset = offset; |
7877 | 66 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
7878 | 66 | if (tag_is_closing(tag_info) ) { |
7879 | 1 | return offset; |
7880 | 1 | } |
7881 | 65 | offset = fDeviceObjectReference(tvb, pinfo, tree, offset); |
7882 | 65 | if (offset <= lastoffset) break; |
7883 | 65 | } |
7884 | 51 | return offset; |
7885 | 52 | } |
7886 | | |
7887 | | /* |
7888 | | SEQ OF ReadAccessSpecification |
7889 | | */ |
7890 | | static unsigned |
7891 | | fListOfGroupMembers(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
7892 | 108 | { |
7893 | 108 | uint8_t tag_no, tag_info; |
7894 | 108 | uint32_t lvt; |
7895 | 108 | unsigned lastoffset = 0; |
7896 | | |
7897 | 135 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
7898 | 134 | lastoffset = offset; |
7899 | 134 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
7900 | 134 | if (tag_is_closing(tag_info) ) { |
7901 | 5 | return offset; |
7902 | 5 | } |
7903 | 129 | offset = fReadAccessSpecification(tvb, pinfo, tree, offset); |
7904 | 129 | if ( offset <= lastoffset ) break; |
7905 | 129 | } |
7906 | 103 | return offset; |
7907 | 108 | } |
7908 | | |
7909 | | static unsigned |
7910 | | // NOLINTNEXTLINE(misc-no-recursion) |
7911 | | fAbstractSyntaxNType(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
7912 | 10.0k | { |
7913 | 10.0k | uint8_t tag_no, tag_info; |
7914 | 10.0k | uint32_t lvt; |
7915 | 10.0k | unsigned lastoffset = 0, depth = 0; |
7916 | 10.0k | char ar[256]; |
7917 | 10.0k | uint32_t save_object_type; |
7918 | 10.0k | bool do_default_handling; |
7919 | | |
7920 | 10.0k | if (propertyIdentifier >= 0) { |
7921 | 10.0k | snprintf(ar, sizeof(ar), "%s: ", |
7922 | 10.0k | val_to_split_str(pinfo->pool, propertyIdentifier, 512, |
7923 | 10.0k | BACnetPropertyIdentifier, |
7924 | 10.0k | ASHRAE_Reserved_Fmt, |
7925 | 10.0k | Vendor_Proprietary_Fmt)); |
7926 | 10.0k | } else { |
7927 | 29 | snprintf(ar, sizeof(ar), "Abstract Type: "); |
7928 | 29 | } |
7929 | | |
7930 | 10.0k | increment_dissection_depth(pinfo); |
7931 | | |
7932 | 120k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
7933 | 119k | lastoffset = offset; |
7934 | 119k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
7935 | 119k | if (tag_is_closing(tag_info)) { /* closing tag, but not for me */ |
7936 | 3.11k | if (depth <= 0) { |
7937 | 2.20k | goto cleanup; |
7938 | 2.20k | } |
7939 | 3.11k | } |
7940 | | |
7941 | 117k | do_default_handling = false; |
7942 | | |
7943 | | /* Application Tags */ |
7944 | 117k | switch (propertyIdentifier) { |
7945 | 2.68k | case 0: /* acked-transitions */ |
7946 | 2.77k | case 35: /* event-enable */ |
7947 | 2.77k | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, |
7948 | 2.77k | BACnetAcknowledgedTransitions); |
7949 | 2.77k | break; |
7950 | 3.16k | case 2: /* action */ |
7951 | | /* loop object is application tagged, |
7952 | | command object is context tagged */ |
7953 | 3.16k | if (tag_is_context_specific(tag_info)) { |
7954 | | /* BACnetActionList */ |
7955 | 865 | offset = fActionList(tvb, pinfo, tree, offset); |
7956 | 2.30k | } else { |
7957 | | /* BACnetAction */ |
7958 | 2.30k | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, |
7959 | 2.30k | BACnetAction); |
7960 | 2.30k | } |
7961 | 3.16k | break; |
7962 | 2.66k | case 7: /* alarm-values*/ |
7963 | 2.66k | switch (object_type) { |
7964 | 14 | case 21: /* life-point */ |
7965 | 14 | case 22: /* life-zone */ |
7966 | 14 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyState); |
7967 | 14 | break; |
7968 | 0 | case 30: /* access-door */ |
7969 | 0 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetDoorAlarmState); |
7970 | 0 | break; |
7971 | 0 | case 31: /* timer */ |
7972 | 0 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetTimerState); |
7973 | 0 | break; |
7974 | 5 | case 36: /* access-zone */ |
7975 | 5 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetAccessZoneOccupancyState); |
7976 | 5 | break; |
7977 | 225 | case 39: /* bitstring-value */ |
7978 | 2.64k | default: |
7979 | 2.64k | if (tag_info) { |
7980 | 1.14k | if (tag_is_opening(tag_info)) { |
7981 | 343 | ++depth; |
7982 | 343 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
7983 | 343 | } |
7984 | 797 | else if (tag_is_closing(tag_info)) { |
7985 | 90 | --depth; |
7986 | 90 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
7987 | 90 | } |
7988 | 707 | else { |
7989 | 707 | offset = fContextTaggedValue(tvb, pinfo, tree, offset, ar); |
7990 | 707 | } |
7991 | 1.14k | } |
7992 | 1.50k | else { |
7993 | 1.50k | offset = fApplicationTypes(tvb, pinfo, tree, offset, ar); |
7994 | 1.50k | } |
7995 | 2.64k | break; |
7996 | 2.66k | } |
7997 | 2.66k | break; |
7998 | 2.66k | case 37: /* event-type */ |
7999 | 318 | offset = fEventType(tvb, pinfo, tree, offset); |
8000 | 318 | break; |
8001 | 3.89k | case 39: /* fault-values */ |
8002 | 3.89k | switch (object_type) { |
8003 | 0 | case 21: /* life-point */ |
8004 | 0 | case 22: /* life-zone */ |
8005 | 0 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyState); |
8006 | 0 | break; |
8007 | 0 | case 30: /* access-door */ |
8008 | 0 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetDoorAlarmState); |
8009 | 0 | break; |
8010 | 0 | case 31: /* timer */ |
8011 | 0 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetTimerState); |
8012 | 0 | break; |
8013 | 26 | case 36: /* access-zone */ |
8014 | 26 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetAccessZoneOccupancyState); |
8015 | 26 | break; |
8016 | 0 | case 39: /* bitstring-value */ |
8017 | 3.87k | default: |
8018 | 3.87k | if (tag_info) { |
8019 | 1.88k | if (tag_is_opening(tag_info)) { |
8020 | 1.12k | ++depth; |
8021 | 1.12k | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
8022 | 1.12k | } |
8023 | 763 | else if (tag_is_closing(tag_info)) { |
8024 | 208 | --depth; |
8025 | 208 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
8026 | 208 | } |
8027 | 555 | else { |
8028 | 555 | offset = fContextTaggedValue(tvb, pinfo, tree, offset, ar); |
8029 | 555 | } |
8030 | 1.88k | } |
8031 | 1.98k | else { |
8032 | 1.98k | offset = fApplicationTypes(tvb, pinfo, tree, offset, ar); |
8033 | 1.98k | } |
8034 | 3.87k | break; |
8035 | 3.89k | } |
8036 | 3.88k | break; |
8037 | 3.88k | case 30: /* BACnetAddressBinding */ |
8038 | 251 | case 331: /* last-key-server */ |
8039 | 251 | offset = fAddressBinding(tvb, pinfo, tree, offset); |
8040 | 251 | break; |
8041 | 168 | case 52: /* limit-enable */ |
8042 | 168 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLimitEnable); |
8043 | 168 | break; |
8044 | 91 | case 54: /* list of object property reference */ |
8045 | 91 | offset = fLOPR(tvb, pinfo, tree, offset); |
8046 | 91 | break; |
8047 | 386 | case 55: /* list-of-session-keys */ |
8048 | 386 | offset = fSessionKey(tvb, pinfo, tree, offset); |
8049 | 386 | break; |
8050 | 79 | case 77: /* object-name */ |
8051 | 79 | offset = fObjectName(tvb, pinfo, tree, offset); |
8052 | 79 | break; |
8053 | 33 | case 79: /* object-type */ |
8054 | 352 | case 96: /* protocol-object-types-supported */ |
8055 | 352 | offset = fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, ar, |
8056 | 352 | BACnetObjectType, 128); |
8057 | 352 | break; |
8058 | 146 | case 97: /* Protocol-Services-Supported */ |
8059 | 146 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, |
8060 | 146 | BACnetServicesSupported); |
8061 | 146 | break; |
8062 | 130 | case 102: /* recipient-list */ |
8063 | 130 | offset = fDestination(tvb, pinfo, tree, offset); |
8064 | 130 | break; |
8065 | 7 | case 107: /* segmentation-supported */ |
8066 | 7 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, |
8067 | 7 | BACnetSegmentation); |
8068 | 7 | break; |
8069 | 73 | case 111: /* Status-Flags */ |
8070 | 73 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, |
8071 | 73 | BACnetStatusFlags); |
8072 | 73 | break; |
8073 | 291 | case 112: /* System-Status */ |
8074 | 291 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, |
8075 | 291 | BACnetDeviceStatus); |
8076 | 291 | break; |
8077 | 92 | case 117: /* units */ |
8078 | 94 | case 455: /* car-load-units */ |
8079 | 94 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, |
8080 | 94 | BACnetEngineeringUnits); |
8081 | 94 | break; |
8082 | 1.30k | case 87: /* priority-array -- accessed as a BACnetARRAY */ |
8083 | 1.30k | if (propertyArrayIndex == 0) { |
8084 | | /* BACnetARRAY index 0 refers to the length |
8085 | | of the array, not the elements of the array */ |
8086 | 262 | offset = fApplicationTypes(tvb, pinfo, tree, offset, ar); |
8087 | 1.04k | } else { |
8088 | 1.04k | offset = fPriorityArray(tvb, pinfo, tree, offset); |
8089 | 1.04k | } |
8090 | 1.30k | break; |
8091 | 118 | case 38: /* exception-schedule */ |
8092 | 118 | if (object_type < 128) { |
8093 | 101 | if (propertyArrayIndex == 0) { |
8094 | | /* BACnetARRAY index 0 refers to the length |
8095 | | of the array, not the elements of the array */ |
8096 | 0 | offset = fApplicationTypes(tvb, pinfo, tree, offset, ar); |
8097 | 101 | } else { |
8098 | 101 | offset = fSpecialEvent(tvb, pinfo, tree, offset); |
8099 | 101 | } |
8100 | 101 | } |
8101 | 118 | break; |
8102 | 16 | case 19: /* controlled-variable-reference */ |
8103 | 23 | case 60: /* manipulated-variable-reference */ |
8104 | 35 | case 78: /* object-property-reference */ |
8105 | 37 | case 181: /* input-reference */ |
8106 | 38 | case 355: /* event-algorithm-inhibit-reference */ |
8107 | 38 | offset = fObjectPropertyReference(tvb, pinfo, tree, offset); |
8108 | 38 | break; |
8109 | 5 | case 132: /* log-device-object-property */ |
8110 | 5 | offset = fDeviceObjectPropertyReference(tvb, pinfo, tree, offset); |
8111 | 5 | break; |
8112 | 137 | case 109: /* Setpoint-Reference */ |
8113 | | /* setpoint-Reference is actually BACnetSetpointReference which is a SEQ of [0] */ |
8114 | 137 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
8115 | 137 | offset = fBACnetObjectPropertyReference(tvb, pinfo, tree, offset); |
8116 | 137 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
8117 | 137 | break; |
8118 | 57 | case 123: /* weekly-schedule -- accessed as a BACnetARRAY */ |
8119 | 57 | if (object_type < 128) { |
8120 | 45 | if (propertyArrayIndex == 0) { |
8121 | | /* BACnetARRAY index 0 refers to the length |
8122 | | of the array, not the elements of the array */ |
8123 | 19 | offset = fApplicationTypes(tvb, pinfo, tree, offset, ar); |
8124 | 26 | } else { |
8125 | 26 | offset = fWeeklySchedule(tvb, pinfo, tree, offset); |
8126 | 26 | } |
8127 | 45 | } |
8128 | 57 | break; |
8129 | 225 | case 127: /* client COV increment */ |
8130 | 225 | offset = fClientCOV(tvb, pinfo, tree, offset); |
8131 | 225 | break; |
8132 | 39 | case 131: /* log-buffer */ |
8133 | 39 | if ( object_type == 61 ) |
8134 | 0 | offset = fAuditLogRecord(tvb, pinfo, tree, offset); |
8135 | 39 | else if ( object_type == 25 ) |
8136 | 0 | offset = fEventLogRecord(tvb, pinfo, tree, offset); |
8137 | 39 | else if ( object_type == 27 ) |
8138 | 0 | offset = fLogMultipleRecord(tvb, pinfo, tree, offset); |
8139 | 39 | else |
8140 | 39 | offset = fLogRecord(tvb, pinfo, tree, offset); |
8141 | 39 | break; |
8142 | 10 | case 159: /* member-of */ |
8143 | 14 | case 165: /* zone-members */ |
8144 | 51 | case 211: /* subordinate-list */ |
8145 | 54 | case 246: /* access-doors */ |
8146 | 120 | case 249: /* access-event-credential */ |
8147 | 130 | case 252: /* accompaniment */ |
8148 | 155 | case 265: /* credentials */ |
8149 | 161 | case 266: /* credentials-in-zone */ |
8150 | 272 | case 277: /* last-credential-added */ |
8151 | 272 | case 279: /* last-credential-removed */ |
8152 | 285 | case 286: /* members */ |
8153 | 332 | case 320: /* zone-from */ |
8154 | 335 | case 321: /* zone-to */ |
8155 | 351 | case 461: /* energy-meter-ref */ |
8156 | 353 | case 491: /* represents */ |
8157 | 353 | offset = fDeviceObjectReference(tvb, pinfo, tree, offset); |
8158 | 353 | break; |
8159 | 1.77k | case 196: /* last-restart-reason */ |
8160 | 1.77k | offset = fRestartReason(tvb, pinfo, tree, offset); |
8161 | 1.77k | break; |
8162 | 33 | case 212: /* actual-shed-level */ |
8163 | 56 | case 214: /* expected-shed-level */ |
8164 | 62 | case 218: /* requested-shed-level */ |
8165 | 62 | offset = fShedLevel(tvb, pinfo, tree, offset); |
8166 | 62 | break; |
8167 | 64 | case 152: /* active-cov-subscriptions */ |
8168 | 64 | offset = fCOVSubscription(tvb, pinfo, tree, offset); |
8169 | 64 | break; |
8170 | 1.87k | case 23: /* date-list */ |
8171 | 1.87k | offset = fCalendarEntry(tvb, pinfo, tree, offset); |
8172 | 1.87k | break; |
8173 | 118 | case 116: /* time-synchronization-recipients */ |
8174 | 159 | case 206: /* utc-time-synchronization-recipients */ |
8175 | 352 | case 202: /* restart-notification-recipients */ |
8176 | 352 | offset = fRecipient(tvb, pinfo, tree, offset); |
8177 | 352 | break; |
8178 | 29.1k | case 83: /* event-parameters */ |
8179 | 29.1k | offset = fEventParameter(tvb, pinfo, tree, offset); |
8180 | 29.1k | break; |
8181 | 81 | case 130: /* event-time-stamp */ |
8182 | 81 | if (propertyArrayIndex == 0) { |
8183 | | /* BACnetARRAY index 0 refers to the length |
8184 | | of the array, not the elements of the array */ |
8185 | 12 | offset = fApplicationTypes(tvb, pinfo, tree, offset, ar); |
8186 | 69 | } else { |
8187 | 69 | offset = fEventTimeStamps(tvb, pinfo, tree, offset); |
8188 | 69 | } |
8189 | 81 | break; |
8190 | 116 | case 197: /* logging-type */ |
8191 | 116 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLoggingType); |
8192 | 116 | break; |
8193 | 563 | case 36: /* event-state */ |
8194 | 563 | offset = fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, ar, BACnetEventState, 64); |
8195 | 563 | break; |
8196 | 47 | case 103: /* reliability */ |
8197 | 47 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetReliability); |
8198 | 47 | break; |
8199 | 1.18k | case 72: /* notify-type */ |
8200 | 1.18k | offset = fNotifyType(tvb, pinfo, tree, offset); |
8201 | 1.18k | break; |
8202 | 57 | case 208: /* node-type */ |
8203 | 57 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetNodeType); |
8204 | 57 | break; |
8205 | 184 | case 231: /* door-status */ |
8206 | 266 | case 450: /* car-door-status */ |
8207 | 266 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetDoorStatus); |
8208 | 266 | break; |
8209 | 83 | case 233: /* lock-status */ |
8210 | 83 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLockStatus); |
8211 | 83 | break; |
8212 | 62 | case 235: /* secured-status */ |
8213 | 62 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetDoorSecuredStatus); |
8214 | 62 | break; |
8215 | 18 | case 158: /* maintenance-required */ |
8216 | 18 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetMaintenance); |
8217 | 18 | break; |
8218 | 103 | case 92: /* program-state */ |
8219 | 103 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetProgramState); |
8220 | 103 | break; |
8221 | 56 | case 90: /* program-change */ |
8222 | 56 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetProgramRequest); |
8223 | 56 | break; |
8224 | 72 | case 100: /* reason-for-halt */ |
8225 | 72 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetProgramError); |
8226 | 72 | break; |
8227 | 2 | case 157: /* last-restore-time */ |
8228 | 2 | offset = fTimeStamp(tvb, pinfo, tree, offset, ar); |
8229 | 2 | break; |
8230 | 103 | case 160: /* mode */ |
8231 | 203 | case 175: /* accepted-modes */ |
8232 | 203 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyMode); |
8233 | 203 | break; |
8234 | 34 | case 163: /* silenced */ |
8235 | 34 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetSilencedState); |
8236 | 34 | break; |
8237 | 173 | case 161: /* operation-expected */ |
8238 | 173 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyOperation); |
8239 | 173 | break; |
8240 | 1 | case 164: /* tracking-value */ |
8241 | 1 | if (object_type == 21 || object_type == 22) /* life-safety-point/zone */ |
8242 | 0 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyState); |
8243 | 1 | else if (object_type == 63) /* color */ |
8244 | 0 | offset = fXyColor(tvb, pinfo, tree, offset, ar); |
8245 | 1 | else if (object_type == 64) /* color-temperature */ |
8246 | 0 | offset = fUnsignedTag(tvb, pinfo, tree, offset, ar); |
8247 | 1 | else if (object_type == 54) /* lighting-output */ |
8248 | 0 | offset = fRealTag(tvb, pinfo, tree, offset, ar); |
8249 | 1 | break; |
8250 | 131 | case 166: /* life-safety-alarm-values */ |
8251 | 131 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLifeSafetyState); |
8252 | 131 | break; |
8253 | 610 | case 41: /* file-access-method */ |
8254 | 610 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetFileAccessMethod); |
8255 | 610 | break; |
8256 | 46 | case 185: /* prescale */ |
8257 | 46 | offset = fPrescale(tvb, pinfo, tree, offset); |
8258 | 46 | break; |
8259 | 40 | case 187: /* scale */ |
8260 | 40 | offset = fScale(tvb, pinfo, tree, offset); |
8261 | 40 | break; |
8262 | 106 | case 189: /* update-time */ |
8263 | 106 | if (object_type == 37) /* credential-data-input */ |
8264 | 0 | offset = fTimeStamp(tvb, pinfo, tree, offset, ar); |
8265 | 106 | else |
8266 | 106 | offset = fDateTime(tvb, pinfo, tree, offset, ar); |
8267 | 106 | break; |
8268 | 185 | case 184: /* logging-record */ |
8269 | 185 | offset = fLoggingRecord(tvb, pinfo, tree, offset); |
8270 | 185 | break; |
8271 | 46 | case 203: /* time-of-device-restart */ |
8272 | 46 | offset = fTimeStamp(tvb, pinfo, tree, offset, ar); |
8273 | 46 | break; |
8274 | 322 | case 226: /* door-alarm-state */ |
8275 | 322 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetDoorAlarmState); |
8276 | 322 | break; |
8277 | 52 | case 228: /* door-members */ |
8278 | 52 | offset = fDoorMembers(tvb, pinfo, tree, offset); |
8279 | 52 | break; |
8280 | 61 | case 234: /* masked-alarm-values */ |
8281 | 61 | offset = fSequenceOfEnums(tvb, pinfo, tree, offset, ar, BACnetDoorAlarmState); |
8282 | 61 | break; |
8283 | 1 | case 248: /* access-event-authentication-factor */ |
8284 | 1 | offset = fAuthenticationFactor(tvb, pinfo, tree, offset); |
8285 | 1 | break; |
8286 | 322 | case 261: /* authorization-mode */ |
8287 | 322 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetAuthorizationMode); |
8288 | 322 | break; |
8289 | 108 | case 53: /* list-of-group-members */ |
8290 | 108 | save_object_type = object_type; |
8291 | 108 | offset = fListOfGroupMembers(tvb, pinfo, tree, offset); |
8292 | 108 | object_type = save_object_type; |
8293 | 108 | break; |
8294 | 143 | case 296: /* occupancy-state */ |
8295 | 143 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetAccessZoneOccupancyState); |
8296 | 143 | break; |
8297 | 73 | case 300: /* passback-mode */ |
8298 | 73 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetAccessPassbackMode); |
8299 | 73 | break; |
8300 | 24 | case 303: /* reason-for-disable */ |
8301 | 24 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetAccessCredentialDisableReason); |
8302 | 24 | break; |
8303 | 4 | case 318: /* user-type */ |
8304 | 4 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetAccessUserType); |
8305 | 4 | break; |
8306 | 297 | case 330: /* key-sets */ |
8307 | 297 | offset = fSecurityKeySet(tvb, pinfo, tree, offset); |
8308 | 297 | break; |
8309 | 0 | case 332: /* network-access-security-policies */ |
8310 | 0 | offset = fNetworkSecurityPolicy(tvb, pinfo, tree, offset); |
8311 | 0 | break; |
8312 | 0 | case 338: /* backup-and-restore-state */ |
8313 | 0 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetBackupState); |
8314 | 0 | break; |
8315 | 2 | case 370: /* write-status */ |
8316 | 2 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetWriteStatus); |
8317 | 2 | break; |
8318 | 0 | case 385: /* transition */ |
8319 | 0 | if (object_type == 54) /* lighting-output */ |
8320 | 0 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLightingTransition); |
8321 | 0 | else if (object_type == 63) /* color */ |
8322 | 0 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetColorTransition); |
8323 | 0 | else if (object_type == 64) /* color-temperature */ |
8324 | 0 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetColorTransition); |
8325 | 0 | break; |
8326 | 52 | case 288: /* negative-access-rules */ |
8327 | 127 | case 302: /* positive-access-rules */ |
8328 | 127 | offset = fAccessRule(tvb, pinfo, tree, offset); |
8329 | 127 | break; |
8330 | 103 | case 304: /* supported-formats */ |
8331 | 103 | offset = fAuthenticationFactorFormat(tvb, pinfo, tree, offset); |
8332 | 103 | break; |
8333 | 155 | case 327: /* base-device-security-policy */ |
8334 | 155 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetSecurityLevel); |
8335 | 155 | break; |
8336 | 49 | case 371: /* property-list */ |
8337 | 49 | offset = fSequenceOfEnums(tvb, pinfo, tree, offset, ar, BACnetPropertyIdentifier); |
8338 | 49 | break; |
8339 | 8.43k | case 358: /* fault-parameters */ |
8340 | 8.43k | offset = fFaultParameter(tvb, pinfo, tree, offset); |
8341 | 8.43k | break; |
8342 | 9 | case 359: /* fault type */ |
8343 | 9 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetFaultType); |
8344 | 9 | break; |
8345 | 76 | case 362: /* subscribed-recipients */ |
8346 | 76 | offset = fEventNotificationSubscription(tvb, pinfo, tree, offset); |
8347 | 76 | break; |
8348 | 57 | case 364: /* authorization-exemptions */ |
8349 | 57 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetAuthorizationExemption); |
8350 | 57 | break; |
8351 | 0 | case 378: /* in-progress */ |
8352 | 0 | if (object_type == 54) /* lighting-output */ |
8353 | 0 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLightingInProgress); |
8354 | 0 | else if (object_type == 63) /* color */ |
8355 | 0 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetColorOperationInProgress); |
8356 | 0 | else if (object_type == 64) /* color-temperature */ |
8357 | 0 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetColorOperationInProgress); |
8358 | 0 | break; |
8359 | 2 | case 380: /* lighting-command */ |
8360 | 2 | offset = fLightingCommand(tvb, pinfo, tree, offset, ar); |
8361 | 2 | break; |
8362 | 105 | case 16: /* change-of-state-time */ |
8363 | 206 | case 71: /* modification-date */ |
8364 | 272 | case 114: /* time-of-active-time-reset */ |
8365 | 1.24k | case 115: /* time-of-state-count-reset */ |
8366 | 1.29k | case 142: /* start-time */ |
8367 | 1.70k | case 143: /* stop-time */ |
8368 | 1.79k | case 149: /* maximum-value-time-stamp */ |
8369 | 2.15k | case 150: /* minimum-value-time-stamp */ |
8370 | 2.38k | case 179: /* count-change-time */ |
8371 | 2.76k | case 192: /* value-change-time */ |
8372 | 2.95k | case 254: /* activation-time */ |
8373 | 3.07k | case 270: /* expiration-time */ |
8374 | 3.12k | case 278: /* last-credential-added-time */ |
8375 | 3.14k | case 280: /* last-credential-removed-time */ |
8376 | 3.16k | case 281: /* last-use-time */ |
8377 | 3.16k | case 392: /* time-of-strike-count-reset */ |
8378 | 3.16k | offset = fDateTime(tvb, pinfo, tree, offset, ar); |
8379 | 3.16k | break; |
8380 | 241 | case 258: /* authentication-policy-list */ |
8381 | 241 | offset = fAuthenticationPolicy(tvb, pinfo, tree, offset); |
8382 | 241 | break; |
8383 | 0 | case 395: /* last-state-change */ |
8384 | 0 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetTimerTransition); |
8385 | 0 | break; |
8386 | 149 | case 396: /* state-change-values */ |
8387 | 149 | offset = fTimerStateChangeValue(tvb, pinfo, tree, offset); |
8388 | 149 | break; |
8389 | 9 | case 398: /* timer-state */ |
8390 | 9 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetTimerState); |
8391 | 9 | break; |
8392 | 27 | case 407: /* bacnet-ip-global-address */ |
8393 | 27 | case 418: /* fd-bbmd-address */ |
8394 | 27 | offset = fHostNPort(tvb, pinfo, tree, offset, ar); |
8395 | 27 | break; |
8396 | 0 | case 408: /* bacnet-ip-mode */ |
8397 | 259 | case 435: /* bacnet-ipv6-mode */ |
8398 | 259 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetIpMode); |
8399 | 259 | break; |
8400 | 97 | case 414: /* bmd-broadcast-distribution-table */ |
8401 | 97 | offset = fBDTEntry(tvb, pinfo, tree, offset, ar); |
8402 | 97 | break; |
8403 | 66 | case 415: /* bbmd-foreign-device-table */ |
8404 | 66 | offset = fFDTEntry(tvb, pinfo, tree, offset, ar); |
8405 | 66 | break; |
8406 | 16 | case 417: /* command */ |
8407 | 16 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetNetworkPortCommand); |
8408 | 16 | break; |
8409 | 0 | case 426: /* network-number-quality */ |
8410 | 0 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetNetworkNumberQuality); |
8411 | 0 | break; |
8412 | 20 | case 427: /* network-type */ |
8413 | 20 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetNetworkType); |
8414 | 20 | break; |
8415 | 87 | case 428: /* routing-table */ |
8416 | 87 | offset = fRouterEntry(tvb, pinfo, tree, offset); |
8417 | 87 | break; |
8418 | 45 | case 429: /* virtual-mac-address-table */ |
8419 | 45 | offset = fVMACEntry(tvb, pinfo, tree, offset); |
8420 | 45 | break; |
8421 | 15 | case 430: /* command-time-array */ |
8422 | 15 | if (propertyArrayIndex == 0) { |
8423 | | /* BACnetARRAY index 0 refers to the length |
8424 | | of the array, not the elements of the array */ |
8425 | 0 | offset = fApplicationTypes(tvb, pinfo, tree, offset, ar); |
8426 | 15 | } else { |
8427 | 15 | offset = fTimeStamp(tvb, pinfo, tree, offset, ar); |
8428 | 15 | } |
8429 | 15 | break; |
8430 | 8 | case 432: /* last-command-time */ |
8431 | 8 | offset = fTimeStamp(tvb, pinfo, tree, offset, ar); |
8432 | 8 | break; |
8433 | 1.46k | case 433: /* value-source */ |
8434 | 1.46k | offset = fValueSource(tvb, pinfo, tree, offset); |
8435 | 1.46k | break; |
8436 | 1 | case 434: /* value-source-array */ |
8437 | 1 | if (propertyArrayIndex == 0) { |
8438 | | /* BACnetARRAY index 0 refers to the length |
8439 | | of the array, not the elements of the array */ |
8440 | 0 | offset = fApplicationTypes(tvb, pinfo, tree, offset, ar); |
8441 | 1 | } else { |
8442 | 1 | offset = fValueSource(tvb, pinfo, tree, offset); |
8443 | 1 | } |
8444 | 1 | break; |
8445 | 2.71k | case 447: /* assigned-landing-calls */ |
8446 | 2.71k | offset = fAssignedLandingCalls(tvb, pinfo, tree, offset); |
8447 | 2.71k | break; |
8448 | 2 | case 448: /* car-assigned-direction */ |
8449 | 8 | case 457: /* car-moving-direction */ |
8450 | 8 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLiftCarDirection); |
8451 | 8 | break; |
8452 | 0 | case 449: /* car-door-command */ |
8453 | 0 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLiftCarDoorCommand); |
8454 | 0 | break; |
8455 | 18 | case 453: /* car-drive-status */ |
8456 | 18 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLiftCarDriveStatus); |
8457 | 18 | break; |
8458 | 0 | case 456: /* car-mode */ |
8459 | 0 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLiftCarMode); |
8460 | 0 | break; |
8461 | 41 | case 462: /* escalator-mode */ |
8462 | 41 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetEscalatorMode); |
8463 | 41 | break; |
8464 | 4 | case 463: /* fault-signals */ |
8465 | 4 | if (propertyArrayIndex == 0) { |
8466 | | /* BACnetARRAY index 0 refers to the length |
8467 | | of the array, not the elements of the array */ |
8468 | 0 | offset = fApplicationTypes(tvb, pinfo, tree, offset, ar); |
8469 | 4 | } else { |
8470 | 4 | if (object_type == 59) /* lift object */ |
8471 | 0 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLiftFault); |
8472 | 4 | else |
8473 | 4 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetEscalatorFault); |
8474 | 4 | } |
8475 | 4 | break; |
8476 | 64 | case 467: /* group-mode */ |
8477 | 64 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetLiftGroupMode); |
8478 | 64 | break; |
8479 | 47 | case 470: /* landing-calls */ |
8480 | 47 | if (propertyArrayIndex == 0) { |
8481 | | /* BACnetARRAY index 0 refers to the length |
8482 | | of the array, not the elements of the array */ |
8483 | 0 | offset = fApplicationTypes(tvb, pinfo, tree, offset, ar); |
8484 | 47 | } else { |
8485 | 47 | offset = fLandingCallStatus(tvb, pinfo, tree, offset); |
8486 | 47 | } |
8487 | 47 | break; |
8488 | 134 | case 471: /* landing-call-control */ |
8489 | 134 | offset = fLandingCallStatus(tvb, pinfo, tree, offset); |
8490 | 134 | break; |
8491 | 827 | case 472: /* landing-door-status */ |
8492 | 827 | if (propertyArrayIndex == 0) { |
8493 | | /* BACnetARRAY index 0 refers to the length |
8494 | | of the array, not the elements of the array */ |
8495 | 0 | offset = fApplicationTypes(tvb, pinfo, tree, offset, ar); |
8496 | 827 | } else { |
8497 | 827 | offset = fLandingDoorStatus(tvb, pinfo, tree, offset); |
8498 | 827 | } |
8499 | 827 | break; |
8500 | 71 | case 477: /* "operation-direction */ |
8501 | 71 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetEscalatorOperationDirection); |
8502 | 71 | break; |
8503 | 404 | case 481: /* active-cov-multiple-subscriptions */ |
8504 | 404 | if (propertyArrayIndex == 0) { |
8505 | | /* BACnetARRAY index 0 refers to the length |
8506 | | of the array, not the elements of the array */ |
8507 | 0 | offset = fApplicationTypes(tvb, pinfo, tree, offset, ar); |
8508 | 404 | } else { |
8509 | 404 | offset = fCOVMultipleSubscription(tvb, pinfo, tree, offset); |
8510 | 404 | } |
8511 | 404 | break; |
8512 | 18 | case 482: /* protocol-level */ |
8513 | 18 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetProtocolLevel); |
8514 | 18 | break; |
8515 | 3 | case 486: /* tags */ |
8516 | 3 | if (propertyArrayIndex == 0) { |
8517 | | /* BACnetARRAY index 0 refers to the length |
8518 | | of the array, not the elements of the array */ |
8519 | 0 | offset = fApplicationTypes(tvb, pinfo, tree, offset, ar); |
8520 | 3 | } else { |
8521 | 3 | offset = fNameValue(tvb, pinfo, tree, offset); |
8522 | 3 | } |
8523 | 3 | break; |
8524 | 2 | case 487: /* subordinate-node-types */ |
8525 | 2 | if (propertyArrayIndex == 0) { |
8526 | | /* BACnetARRAY index 0 refers to the length |
8527 | | of the array, not the elements of the array */ |
8528 | 0 | offset = fApplicationTypes(tvb, pinfo, tree, offset, ar); |
8529 | 2 | } else { |
8530 | 2 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetNodeType); |
8531 | 2 | } |
8532 | 2 | break; |
8533 | 1.18k | case 488: /* subordinate-tags */ |
8534 | 1.18k | if (propertyArrayIndex == 0) { |
8535 | | /* BACnetARRAY index 0 refers to the length |
8536 | | of the array, not the elements of the array */ |
8537 | 0 | offset = fApplicationTypes(tvb, pinfo, tree, offset, ar); |
8538 | 1.18k | } else { |
8539 | 1.18k | offset = fNameValueCollection(tvb, pinfo, tree, offset); |
8540 | 1.18k | } |
8541 | 1.18k | break; |
8542 | 82 | case 489: /* subordinate-relationship */ |
8543 | 82 | if (propertyArrayIndex == 0) { |
8544 | | /* BACnetARRAY index 0 refers to the length |
8545 | | of the array, not the elements of the array */ |
8546 | 0 | offset = fApplicationTypes(tvb, pinfo, tree, offset, ar); |
8547 | 82 | } else { |
8548 | 82 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetRelationship); |
8549 | 82 | } |
8550 | 82 | break; |
8551 | 27 | case 490: /* default-subordinate-relationship */ |
8552 | 27 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetRelationship); |
8553 | 27 | break; |
8554 | 23 | case 494: /* stages */ |
8555 | 23 | if (propertyArrayIndex == 0) { |
8556 | | /* BACnetARRAY index 0 refers to the length |
8557 | | of the array, not the elements of the array */ |
8558 | 0 | offset = fApplicationTypes(tvb, pinfo, tree, offset, ar); |
8559 | 23 | } else { |
8560 | 23 | offset = fStageLimitValue(tvb, pinfo, tree, offset); |
8561 | 23 | } |
8562 | 23 | break; |
8563 | 16 | case 498: /* audit-level */ |
8564 | 16 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetAuditLevel); |
8565 | 16 | break; |
8566 | 1 | case 500: /* audit-priority-filter */ |
8567 | 1 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetAuditPriorityFilter); |
8568 | 1 | break; |
8569 | 0 | case 501: /* auditable-operations */ |
8570 | 0 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetAuditOperation); |
8571 | 0 | break; |
8572 | 44 | case 504: /* monitored-objects */ |
8573 | 44 | if (propertyArrayIndex == 0) { |
8574 | | /* BACnetARRAY index 0 refers to the length |
8575 | | of the array, not the elements of the array */ |
8576 | 0 | offset = fApplicationTypes(tvb, pinfo, tree, offset, ar); |
8577 | 44 | } else { |
8578 | 44 | offset = fObjectSelector(tvb, pinfo, tree, offset); |
8579 | 44 | } |
8580 | 44 | break; |
8581 | 77 | case 510: /* command-validation-result */ |
8582 | 77 | case 4194307: /* current-health */ |
8583 | 77 | offset = fHealth(tvb, pinfo, tree, offset); |
8584 | 77 | break; |
8585 | 47 | case 4194312: /* sc-direct-connect-connection-status */ |
8586 | 47 | offset = fSCDirectConnection(tvb, pinfo, tree, offset); |
8587 | 47 | break; |
8588 | 0 | case 4194315: /* sc-failed-connection-requests */ |
8589 | 0 | offset = fSCFailedConnectionRequest(tvb, pinfo, tree, offset); |
8590 | 0 | break; |
8591 | 0 | case 4194316: /* sc-failover-hub-connection-status */ |
8592 | 0 | case 4194324: /* sc-primary-hub-connection-status */ |
8593 | 0 | offset = fSCHubConnection(tvb, pinfo, tree, offset); |
8594 | 0 | break; |
8595 | 0 | case 4194318: /* sc_hub_connector_state */ |
8596 | 0 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, ar, BACnetSCHubConnectorState); |
8597 | 0 | break; |
8598 | 40 | case 4194321: /* sc-hub-function-connection-status */ |
8599 | 40 | offset = fSCHubFunctionConnection(tvb, pinfo, tree, offset); |
8600 | 40 | break; |
8601 | 0 | case 4194330: /* default-color */ |
8602 | 0 | offset = fXyColor(tvb, pinfo, tree, offset, ar); |
8603 | 0 | break; |
8604 | 0 | case 4194334: /* color-command */ |
8605 | 0 | offset = fColorCommand(tvb, pinfo, tree, offset, ar); |
8606 | 0 | break; |
8607 | 0 | case 4194339: /* device-address-proxy-table */ |
8608 | 0 | offset = fDeviceAddressProxyTableEntry(tvb, pinfo, tree, offset, ar); |
8609 | 0 | break; |
8610 | 0 | case 4194343: /* authorization-cache */ |
8611 | 0 | offset = fAccessToken(tvb, pinfo, tree, offset, ar); |
8612 | 0 | break; |
8613 | 0 | case 4194345: /* authorization-policy */ |
8614 | 0 | offset = fAuthorizationPolicy(tvb, pinfo, tree, offset, ar); |
8615 | 0 | break; |
8616 | 0 | case 4194346: /* authorization-scope */ |
8617 | 0 | offset = fAuthorizationScopeDescription(tvb, pinfo, tree, offset, ar); |
8618 | 0 | break; |
8619 | 0 | case 4194347: /* authorization-server */ |
8620 | 0 | offset = fAuthorizationServer(tvb, pinfo, tree, offset, ar); |
8621 | 0 | break; |
8622 | 0 | case 4194348: /* authorization-status */ |
8623 | 0 | offset = fAuthorizationStatus(tvb, pinfo, tree, offset, ar); |
8624 | 0 | break; |
8625 | | |
8626 | 28.9k | case 85: /* present-value */ |
8627 | 28.9k | if ( object_type == 11 ) /* group object handling of present-value */ |
8628 | 684 | { |
8629 | 684 | offset = fReadAccessResult(tvb, pinfo, tree, offset); |
8630 | 684 | } |
8631 | 28.2k | else if (object_type == 30) /* access-door object */ |
8632 | 313 | { |
8633 | 313 | offset = fPresentValue(tvb, pinfo, tree, offset, BACnetDoorValue, 0, BACAPP_PRESENT_VALUE_ENUM); |
8634 | 313 | } |
8635 | 27.9k | else if (object_type == 21) /* life-point */ |
8636 | 590 | { |
8637 | 590 | offset = fPresentValue(tvb, pinfo, tree, offset, BACnetLifeSafetyState, 0, BACAPP_PRESENT_VALUE_ENUM); |
8638 | 590 | } |
8639 | 27.3k | else if (object_type == 22) /* life-zone */ |
8640 | 1.51k | { |
8641 | 1.51k | offset = fPresentValue(tvb, pinfo, tree, offset, BACnetLifeSafetyState, 0, BACAPP_PRESENT_VALUE_ENUM); |
8642 | 1.51k | } |
8643 | 25.8k | else if (object_type == 53) /* channel object */ |
8644 | 105 | { |
8645 | 105 | offset = fChannelValue(tvb, pinfo, tree, offset, ar); |
8646 | 105 | } |
8647 | 25.7k | else if (object_type == 37) /* credential-data-input */ |
8648 | 10 | { |
8649 | 10 | offset = fAuthenticationFactor(tvb, pinfo, tree, offset); |
8650 | 10 | } |
8651 | 25.7k | else if (object_type == 26) /* global-group */ |
8652 | 842 | { |
8653 | 842 | offset = fPropertyAccessResult(tvb, pinfo, tree, offset); |
8654 | 842 | } |
8655 | 24.8k | else if (object_type == 28) /* loac-control */ |
8656 | 875 | { |
8657 | 875 | offset = fPresentValue(tvb, pinfo, tree, offset, BACnetShedState, 0, BACAPP_PRESENT_VALUE_ENUM); |
8658 | 875 | } |
8659 | 23.9k | else if (object_type == 43) /* date-time-pattern-value */ |
8660 | 230 | { |
8661 | 230 | offset = fDateTime(tvb, pinfo, tree, offset, ar); |
8662 | 230 | } |
8663 | 23.7k | else if (object_type == 44) /* date-time-value */ |
8664 | 525 | { |
8665 | 525 | offset = fDateTime(tvb, pinfo, tree, offset, ar); |
8666 | 525 | } |
8667 | 23.2k | else if (object_type == 63) /* color */ |
8668 | 73 | { |
8669 | 73 | offset = fXyColor(tvb, pinfo, tree, offset, ar); |
8670 | 73 | } |
8671 | 23.1k | else |
8672 | 23.1k | { |
8673 | 23.1k | if (!tag_info) { |
8674 | 18.4k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
8675 | | // application tag number above 12 reserved for ASHRAE |
8676 | 18.4k | if (!tag_is_context_specific(tag_info) && tag_no <= 12) { |
8677 | 18.2k | offset = fPresentValue(tvb, pinfo, tree, offset, NULL, 0, (BacappPresentValueType) tag_no); |
8678 | 18.2k | } |
8679 | 18.4k | } else { |
8680 | 4.70k | do_default_handling = true; |
8681 | 4.70k | } |
8682 | 23.1k | } |
8683 | 28.9k | break; |
8684 | 11.9k | default: |
8685 | 11.9k | do_default_handling = true; |
8686 | 11.9k | break; |
8687 | 117k | } |
8688 | 115k | if (do_default_handling) { |
8689 | 16.6k | if (tag_info) { |
8690 | 8.74k | if (tag_is_opening(tag_info)) { |
8691 | 2.83k | ++depth; |
8692 | 2.83k | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
8693 | 5.91k | } else if (tag_is_closing(tag_info)) { |
8694 | 610 | --depth; |
8695 | 610 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
8696 | 5.30k | } else { |
8697 | 5.30k | offset = fContextTaggedValue(tvb, pinfo, tree, offset, ar); |
8698 | 5.30k | } |
8699 | 8.74k | } else { |
8700 | 7.92k | offset = fApplicationTypes(tvb, pinfo, tree, offset, ar); |
8701 | 7.92k | } |
8702 | 16.6k | } |
8703 | 115k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
8704 | 115k | } |
8705 | | |
8706 | 7.98k | cleanup: |
8707 | 7.98k | decrement_dissection_depth(pinfo); |
8708 | 7.98k | return offset; |
8709 | 10.0k | } |
8710 | | |
8711 | | static unsigned |
8712 | | // NOLINTNEXTLINE(misc-no-recursion) |
8713 | | fPropertyValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, uint8_t tag_info) |
8714 | 3.94k | { |
8715 | 3.94k | uint8_t tag_no; |
8716 | 3.94k | uint32_t lvt; |
8717 | | |
8718 | 3.94k | if (tag_is_opening(tag_info)) { |
8719 | 3.85k | offset += fTagHeaderTree(tvb, pinfo, tree, offset, |
8720 | 3.85k | &tag_no, &tag_info, &lvt); |
8721 | 3.85k | offset = fAbstractSyntaxNType(tvb, pinfo, tree, offset); |
8722 | 3.85k | if (tvb_reported_length_remaining(tvb, offset) > 0) { |
8723 | 2.64k | offset += fTagHeaderTree(tvb, pinfo, tree, offset, |
8724 | 2.64k | &tag_no, &tag_info, &lvt); |
8725 | 2.64k | } |
8726 | 3.85k | } else { |
8727 | 83 | proto_tree_add_expert(tree, pinfo, &ei_bacapp_opening_tag, tvb, offset, -1); |
8728 | 83 | offset = tvb_reported_length(tvb); |
8729 | 83 | } |
8730 | | |
8731 | 3.94k | return offset; |
8732 | 3.94k | } |
8733 | | |
8734 | | |
8735 | | static unsigned |
8736 | | // NOLINTNEXTLINE(misc-no-recursion) |
8737 | | fPropertyIdentifierValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, uint8_t tagoffset) |
8738 | 6.61k | { |
8739 | 6.61k | unsigned lastoffset = offset; |
8740 | 6.61k | uint8_t tag_no, tag_info; |
8741 | 6.61k | uint32_t lvt; |
8742 | | |
8743 | 6.61k | offset = fPropertyReference(tvb, pinfo, tree, offset, tagoffset, 0); |
8744 | 6.61k | if (offset > lastoffset) { |
8745 | 2.40k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
8746 | 2.40k | if (tag_no == tagoffset+2) { /* Value - might not be present in ReadAccessResult */ |
8747 | 755 | offset = fPropertyValue(tvb, pinfo, tree, offset, tag_info); |
8748 | 755 | } |
8749 | 2.40k | } |
8750 | 6.61k | return offset; |
8751 | 6.61k | } |
8752 | | |
8753 | | static unsigned |
8754 | | // NOLINTNEXTLINE(misc-no-recursion) |
8755 | | fBACnetPropertyValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
8756 | 4.36k | { |
8757 | 4.36k | unsigned lastoffset = 0; |
8758 | 4.36k | uint8_t tag_no, tag_info; |
8759 | 4.36k | uint32_t lvt; |
8760 | | |
8761 | 6.52k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
8762 | 6.29k | lastoffset = offset; |
8763 | 6.29k | offset = fPropertyIdentifierValue(tvb, pinfo, tree, offset, 0); |
8764 | 6.29k | if (offset > lastoffset) { |
8765 | | /* detect optional priority |
8766 | | by looking to see if the next tag is context tag number 3 */ |
8767 | 1.99k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
8768 | 1.99k | if (tag_is_context_specific(tag_info) && (tag_no == 3)) |
8769 | 53 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "Priority: "); |
8770 | 1.99k | } |
8771 | 6.29k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
8772 | 6.29k | } |
8773 | 4.36k | return offset; |
8774 | 4.36k | } |
8775 | | |
8776 | | static unsigned |
8777 | | fSubscribeCOVPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
8778 | 109 | { |
8779 | 109 | unsigned lastoffset = 0, len; |
8780 | 109 | uint8_t tag_no, tag_info; |
8781 | 109 | uint32_t lvt; |
8782 | 109 | proto_tree *subtree = tree; |
8783 | | |
8784 | 3.68k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
8785 | 3.67k | lastoffset = offset; |
8786 | 3.67k | len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
8787 | 3.67k | if (tag_is_closing(tag_info)) { |
8788 | 740 | offset += len; |
8789 | 740 | subtree = tree; |
8790 | 740 | continue; |
8791 | 740 | } |
8792 | | |
8793 | 2.93k | switch (tag_no) { |
8794 | 1.77k | case 0: /* ProcessId */ |
8795 | 1.77k | offset = fUnsignedTag(tvb, pinfo, tree, offset, "subscriber Process Id: "); |
8796 | 1.77k | break; |
8797 | 218 | case 1: /* monitored ObjectId */ |
8798 | 218 | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_object_identifier); |
8799 | 218 | break; |
8800 | 262 | case 2: /* issueConfirmedNotifications */ |
8801 | 262 | offset = fBooleanTag(tvb, pinfo, tree, offset, "issue Confirmed Notifications: "); |
8802 | 262 | break; |
8803 | 345 | case 3: /* life time */ |
8804 | 345 | offset = fTimeSpan(tvb, pinfo, tree, offset, "life time"); |
8805 | 345 | break; |
8806 | 128 | case 4: /* monitoredPropertyIdentifier */ |
8807 | 128 | if (tag_is_opening(tag_info)) { |
8808 | 114 | subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "monitoredPropertyIdentifier"); |
8809 | 114 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
8810 | 114 | offset = fBACnetPropertyReference(tvb, pinfo, subtree, offset, 1); |
8811 | 114 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
8812 | 114 | } else { |
8813 | 14 | expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag); |
8814 | 14 | } |
8815 | 128 | break; |
8816 | 136 | case 5: /* covIncrement */ |
8817 | 136 | offset = fRealTag(tvb, pinfo, tree, offset, "COV Increment: "); |
8818 | 136 | break; |
8819 | 67 | default: |
8820 | 67 | return offset; |
8821 | 2.93k | } |
8822 | 2.85k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
8823 | 2.85k | } |
8824 | 30 | return offset; |
8825 | 109 | } |
8826 | | |
8827 | | static unsigned |
8828 | | fSubscribeCOVPropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
8829 | 133 | { |
8830 | 133 | unsigned lastoffset = 0, len; |
8831 | 133 | uint8_t tag_no, tag_info; |
8832 | 133 | uint32_t lvt; |
8833 | 133 | proto_tree *subtree = tree; |
8834 | 133 | proto_tree *subsubtree = tree; |
8835 | | |
8836 | 4.06k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
8837 | 4.04k | lastoffset = offset; |
8838 | 4.04k | len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
8839 | 4.04k | if (tag_is_closing(tag_info)) { |
8840 | 1.30k | offset += len; |
8841 | 1.30k | subtree = tree; |
8842 | 1.30k | continue; |
8843 | 1.30k | } |
8844 | | |
8845 | 2.73k | switch (tag_no) { |
8846 | 1.32k | case 0: /* ProcessId */ |
8847 | 1.32k | offset = fUnsignedTag(tvb, pinfo, tree, offset, "subscriber Process Id: "); |
8848 | 1.32k | break; |
8849 | 750 | case 1: /* issueConfirmedNotifications */ |
8850 | 750 | offset = fBooleanTag(tvb, pinfo, tree, offset, "issue Confirmed Notifications: "); |
8851 | 750 | break; |
8852 | 246 | case 2: /* life time */ |
8853 | 246 | offset = fTimeSpan(tvb, pinfo, tree, offset, "life time"); |
8854 | 246 | break; |
8855 | 287 | case 3: /* notification delay */ |
8856 | 287 | offset = fTimeSpan(tvb, pinfo, tree, offset, "notification delay"); |
8857 | 287 | break; |
8858 | 55 | case 4: /* list-of-cov-subscription-specifications */ |
8859 | 55 | if (tag_is_opening(tag_info)) { |
8860 | 43 | subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "list-of-cov-subscription-specifications: "); |
8861 | 43 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
8862 | | |
8863 | 251 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
8864 | 248 | lastoffset = offset; |
8865 | 248 | len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
8866 | 248 | if (tag_is_closing(tag_info)) { |
8867 | 22 | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
8868 | 22 | offset += len; |
8869 | 22 | subtree = tree; |
8870 | 22 | break; |
8871 | 22 | } |
8872 | | |
8873 | 226 | switch (tag_no) { |
8874 | 190 | case 0: /* monitored-object-identifier */ |
8875 | 190 | offset = fObjectIdentifier(tvb, pinfo, subtree, offset, hf_bacapp_object_identifier); |
8876 | 190 | break; |
8877 | 28 | case 1: /* list-of-cov-references */ |
8878 | 28 | if (tag_is_opening(tag_info)) { |
8879 | 26 | subsubtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "list-of-cov-references: "); |
8880 | 26 | offset += fTagHeaderTree(tvb, pinfo, subsubtree, offset, &tag_no, &tag_info, &lvt); |
8881 | | |
8882 | 64 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
8883 | 64 | lastoffset = offset; |
8884 | 64 | len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
8885 | 64 | if (tag_is_closing(tag_info)) { |
8886 | 19 | fTagHeaderTree(tvb, pinfo, subsubtree, offset, &tag_no, &tag_info, &lvt); |
8887 | 19 | offset += len; |
8888 | 19 | break; |
8889 | 19 | } |
8890 | | |
8891 | 45 | switch (tag_no) { |
8892 | 4 | case 0: /* monitored-property */ |
8893 | 4 | if (tag_is_opening(tag_info)) { |
8894 | 1 | offset += fTagHeaderTree(tvb, pinfo, subsubtree, offset, &tag_no, &tag_info, &lvt); |
8895 | 1 | offset = fBACnetPropertyReference(tvb, pinfo, subsubtree, offset, 1); |
8896 | 1 | offset += fTagHeaderTree(tvb, pinfo, subsubtree, offset, &tag_no, &tag_info, &lvt); |
8897 | 1 | } |
8898 | 3 | else { |
8899 | 3 | expert_add_info(pinfo, subsubtree, &ei_bacapp_bad_tag); |
8900 | 3 | } |
8901 | 4 | break; |
8902 | 32 | case 1: /* cov-increment */ |
8903 | 32 | offset = fRealTag(tvb, pinfo, subsubtree, offset, "COV Increment: "); |
8904 | 32 | break; |
8905 | 5 | case 2: /* timestamped */ |
8906 | 5 | offset = fBooleanTag(tvb, pinfo, subsubtree, offset, "timestamped: "); |
8907 | 5 | break; |
8908 | 4 | default: |
8909 | 4 | return offset; |
8910 | 45 | } |
8911 | 41 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
8912 | 41 | } |
8913 | 26 | } |
8914 | 2 | else { |
8915 | 2 | expert_add_info(pinfo, subsubtree, &ei_bacapp_bad_tag); |
8916 | 2 | } |
8917 | 24 | break; |
8918 | 24 | default: |
8919 | 8 | return offset; |
8920 | 226 | } |
8921 | 213 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
8922 | 213 | } |
8923 | 43 | } |
8924 | 12 | else { |
8925 | 12 | expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag); |
8926 | 12 | } |
8927 | 42 | break; |
8928 | 75 | default: |
8929 | 75 | return offset; |
8930 | 2.73k | } |
8931 | 2.63k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
8932 | 2.63k | } |
8933 | 37 | return offset; |
8934 | 133 | } |
8935 | | |
8936 | | static unsigned |
8937 | | fSubscribeCOVPropertyMultipleError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
8938 | 87 | { |
8939 | 87 | unsigned lastoffset = 0, len; |
8940 | 87 | uint8_t tag_no, tag_info; |
8941 | 87 | uint32_t lvt; |
8942 | | |
8943 | 419 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
8944 | 411 | lastoffset = offset; |
8945 | 411 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
8946 | 411 | if (tag_is_closing(tag_info)) { |
8947 | 10 | len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
8948 | 10 | offset += len; |
8949 | 10 | break; |
8950 | 10 | } |
8951 | | |
8952 | 401 | switch (tag_no) { |
8953 | 298 | case 0: /* normal error */ |
8954 | 298 | if (tag_is_opening(tag_info)) { |
8955 | 1 | offset = fContextTaggedError(tvb, pinfo, tree, offset); |
8956 | 1 | } |
8957 | 297 | else { |
8958 | 297 | offset = fError(tvb, pinfo, tree, offset); |
8959 | 297 | } |
8960 | 298 | break; |
8961 | 83 | case 1: /* first-failed-subscription */ |
8962 | 83 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
8963 | | |
8964 | 616 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
8965 | 611 | lastoffset = offset; |
8966 | 611 | len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
8967 | 611 | if (tag_is_closing(tag_info)) { |
8968 | 32 | fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
8969 | 32 | offset += len; |
8970 | 32 | break; |
8971 | 32 | } |
8972 | | |
8973 | 579 | switch (tag_no) { |
8974 | 148 | case 0: /* monitored-object-identifier */ |
8975 | 148 | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_object_identifier); |
8976 | 148 | break; |
8977 | 292 | case 1: /* monitored-property-reference */ |
8978 | 292 | if (tag_is_opening(tag_info)) { |
8979 | 272 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
8980 | 272 | offset = fBACnetPropertyReference(tvb, pinfo, tree, offset, 1); |
8981 | 272 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
8982 | 272 | } |
8983 | 20 | else { |
8984 | 20 | expert_add_info(pinfo, tree, &ei_bacapp_bad_tag); |
8985 | 20 | } |
8986 | 292 | break; |
8987 | 115 | case 2: /* error-type */ |
8988 | 115 | offset = fContextTaggedError(tvb, pinfo, tree, offset); |
8989 | 115 | break; |
8990 | 23 | default: |
8991 | 23 | return offset; |
8992 | 579 | } |
8993 | 553 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
8994 | 553 | } |
8995 | 57 | break; |
8996 | 57 | default: |
8997 | 20 | return offset; |
8998 | 401 | } |
8999 | 352 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
9000 | 352 | } |
9001 | 38 | return offset; |
9002 | 87 | } |
9003 | | |
9004 | | static unsigned |
9005 | | fSubscribeCOVRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
9006 | 79 | { |
9007 | 79 | return fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset); |
9008 | 79 | } |
9009 | | |
9010 | | static unsigned |
9011 | | fWhoHas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
9012 | 50 | { |
9013 | 50 | unsigned lastoffset = 0; |
9014 | | |
9015 | 1.36k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
9016 | 1.35k | lastoffset = offset; |
9017 | | |
9018 | 1.35k | switch (fTagNo(tvb, offset)) { |
9019 | 854 | case 0: /* deviceInstanceLowLimit */ |
9020 | 854 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "device Instance Low Limit: "); |
9021 | 854 | break; |
9022 | 280 | case 1: /* deviceInstanceHighLimit */ |
9023 | 280 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "device Instance High Limit: "); |
9024 | 280 | break; |
9025 | 71 | case 2: /* BACnetObjectId */ |
9026 | 71 | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_object_identifier); |
9027 | 71 | break; |
9028 | 112 | case 3: /* ObjectName */ |
9029 | 112 | offset = fObjectName(tvb, pinfo, tree, offset); |
9030 | 112 | break; |
9031 | 34 | default: |
9032 | 34 | return offset; |
9033 | 1.35k | } |
9034 | 1.31k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
9035 | 1.31k | } |
9036 | 11 | return offset; |
9037 | 50 | } |
9038 | | |
9039 | | |
9040 | | static unsigned |
9041 | | fDailySchedule(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, unsigned offset) |
9042 | 38 | { |
9043 | 38 | unsigned lastoffset = 0; |
9044 | 38 | uint8_t tag_no, tag_info; |
9045 | 38 | uint32_t lvt; |
9046 | | |
9047 | 38 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
9048 | 38 | if (tag_is_opening(tag_info) && tag_no == 0) { |
9049 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* opening context tag 0 */ |
9050 | 0 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
9051 | 0 | lastoffset = offset; |
9052 | 0 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
9053 | 0 | if (tag_is_closing(tag_info)) { |
9054 | | /* should be closing context tag 0 */ |
9055 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
9056 | 0 | return offset; |
9057 | 0 | } |
9058 | | |
9059 | 0 | offset = fTimeValue(tvb, pinfo, subtree, offset); |
9060 | 0 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
9061 | 0 | } |
9062 | 38 | } else if ((tag_no == 0) && (lvt == 0)) { |
9063 | | /* not sure null (empty array element) is legal */ |
9064 | 12 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
9065 | 12 | } |
9066 | 38 | return offset; |
9067 | 38 | } |
9068 | | |
9069 | | /** |
9070 | | * BACnetHealth ::= SEQUENCE { |
9071 | | * timestamp [0] BACnetDateTime, |
9072 | | * result [1] Error, |
9073 | | * property [2] BACnetPropertyIdentifier OPTIONAL, |
9074 | | * details [3] CharacterString OPTIONAL |
9075 | | * } |
9076 | | * @param tvb the tv buffer of the current data |
9077 | | * @param pinfo the packet info of the current data |
9078 | | * @param tree the tree to append this item to |
9079 | | * @param offset the offset in the tvb |
9080 | | * @return modified offset |
9081 | | */ |
9082 | | static unsigned |
9083 | | fHealth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
9084 | 77 | { |
9085 | 77 | unsigned lastoffset = 0; |
9086 | 77 | uint8_t tag_no, tag_info; |
9087 | 77 | uint32_t lvt; |
9088 | | |
9089 | 738 | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
9090 | 737 | lastoffset = offset; |
9091 | | /* check the tag. A closing tag means we are done */ |
9092 | 737 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
9093 | 737 | if (tag_is_closing(tag_info)) { |
9094 | 11 | return offset; |
9095 | 11 | } |
9096 | 726 | switch (tag_no) { |
9097 | 456 | case 0: /* timestamp */ |
9098 | 456 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9099 | 456 | offset = fDateTime(tvb, pinfo, tree, offset, "timestamp: "); |
9100 | 456 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9101 | 456 | break; |
9102 | 110 | case 1: /* result */ |
9103 | 110 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9104 | 110 | offset = fError(tvb, pinfo, tree, offset); |
9105 | 110 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9106 | 110 | break; |
9107 | 37 | case 2: /* property - OPTIONAL*/ |
9108 | 37 | offset = fPropertyIdentifier(tvb, pinfo, tree, offset); |
9109 | 37 | break; |
9110 | 76 | case 3: /* details - OPTIONAL */ |
9111 | 76 | offset = fCharacterString(tvb, pinfo, tree, offset, "details: "); |
9112 | 76 | break; |
9113 | 47 | default: |
9114 | 47 | return offset; |
9115 | 726 | } |
9116 | 667 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
9117 | 667 | } |
9118 | 7 | return offset; |
9119 | 77 | } |
9120 | | |
9121 | | /** |
9122 | | * BACnetSCDirectConnection ::= SEQUENCE { |
9123 | | * uri [0] CharacterString |
9124 | | * connection-state [1] BACnetSCConnectionState, |
9125 | | * connect-timestamp [2] BACnetDateTime, |
9126 | | * disconnect-timestamp [3] BACnetDateTime, |
9127 | | * peer-address [4] BACnetHostNPort, |
9128 | | * peer-vmac [5] OCTET STRING (SIZE(6)) |
9129 | | * peer-uuid [6] OCTET STRING (SIZE(16)) |
9130 | | * error [7] Error OPTIONAL |
9131 | | * error-details [8] CharacterString OPTIONAL |
9132 | | * } |
9133 | | * @param tvb the tv buffer of the current data |
9134 | | * @param pinfo the packet info of the current data |
9135 | | * @param tree the tree to append this item to |
9136 | | * @param offset the offset in the tvb |
9137 | | * @return modified offset |
9138 | | */ |
9139 | | static unsigned |
9140 | | fSCDirectConnection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
9141 | 47 | { |
9142 | 47 | unsigned lastoffset = 0; |
9143 | 47 | uint8_t tag_no, tag_info; |
9144 | 47 | uint32_t lvt; |
9145 | | |
9146 | 583 | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
9147 | 581 | lastoffset = offset; |
9148 | | /* check the tag. A closing tag means we are done */ |
9149 | 581 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
9150 | 581 | if (tag_is_closing(tag_info)) { |
9151 | 8 | return offset; |
9152 | 8 | } |
9153 | 573 | switch (tag_no) { |
9154 | 124 | case 0: /* uri */ |
9155 | 124 | offset = fCharacterString(tvb, pinfo, tree, offset, "uri: "); |
9156 | 124 | break; |
9157 | 7 | case 1: /* connection-state */ |
9158 | 7 | offset = fEnumeratedTag(tvb, pinfo, tree, offset, "connection-state: ", BACnetSCConnectionState); |
9159 | 7 | break; |
9160 | 22 | case 2: /* connect-timestamp */ |
9161 | 22 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9162 | 22 | offset = fDateTime(tvb, pinfo, tree, offset, "connect-timestamp: "); |
9163 | 22 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9164 | 22 | break; |
9165 | 55 | case 3: /* disconnect-timestamp */ |
9166 | 55 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9167 | 55 | offset = fDateTime(tvb, pinfo, tree, offset, "disconnect-timestamp: "); |
9168 | 55 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9169 | 55 | break; |
9170 | 147 | case 4: /* peer-address */ |
9171 | 147 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9172 | 147 | offset = fHostNPort(tvb, pinfo, tree, offset,"peer-address: "); |
9173 | 147 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9174 | 147 | break; |
9175 | 45 | case 5: /* peer-vmac */ |
9176 | 45 | offset = fOctetString(tvb, pinfo, tree, offset, "peer-vmac: ", lvt); |
9177 | 45 | break; |
9178 | 47 | case 6: /* peer-uuid */ |
9179 | 47 | offset = fOctetString(tvb, pinfo, tree, offset, "peer-uuid: ", lvt); |
9180 | 47 | break; |
9181 | 97 | case 7: /* error */ |
9182 | 97 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9183 | 97 | offset = fError(tvb, pinfo, tree, offset); |
9184 | 97 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9185 | 97 | break; |
9186 | 12 | case 8: /* details - OPTIONAL */ |
9187 | 12 | offset = fCharacterString(tvb, pinfo, tree, offset, "details: "); |
9188 | 12 | break; |
9189 | 17 | default: |
9190 | 17 | return offset; |
9191 | 573 | } |
9192 | 536 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
9193 | 536 | } |
9194 | 2 | return offset; |
9195 | 47 | } |
9196 | | |
9197 | | /** |
9198 | | * BACnetSCFailedConnectionRequest ::= SEQUENCE { |
9199 | | * timestamp [0] BACnetDateTime, |
9200 | | * peer-address [1] BACnetHostNPort, |
9201 | | * peer-vmac [2] OCTET STRING (SIZE(6)) |
9202 | | * peer-uuid [3] OCTET STRING (SIZE(16)) |
9203 | | * error [4] Error OPTIONAL |
9204 | | * error-details [5] CharacterString OPTIONAL |
9205 | | * } |
9206 | | * @param tvb the tv buffer of the current data |
9207 | | * @param pinfo the packet info of the current data |
9208 | | * @param tree the tree to append this item to |
9209 | | * @param offset the offset in the tvb |
9210 | | * @return modified offset |
9211 | | */ |
9212 | | static unsigned |
9213 | | fSCFailedConnectionRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
9214 | 0 | { |
9215 | 0 | unsigned lastoffset = 0; |
9216 | 0 | uint8_t tag_no, tag_info; |
9217 | 0 | uint32_t lvt; |
9218 | |
|
9219 | 0 | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
9220 | 0 | lastoffset = offset; |
9221 | | /* check the tag. A closing tag means we are done */ |
9222 | 0 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
9223 | 0 | if (tag_is_closing(tag_info)) { |
9224 | 0 | return offset; |
9225 | 0 | } |
9226 | 0 | switch (tag_no) { |
9227 | 0 | case 0: /* timestamp */ |
9228 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9229 | 0 | offset = fDateTime(tvb, pinfo, tree, offset, "connect-timestamp: "); |
9230 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9231 | 0 | break; |
9232 | 0 | case 1: /* peer-address */ |
9233 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9234 | 0 | offset = fHostNPort(tvb, pinfo, tree, offset,"peer-address: "); |
9235 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9236 | 0 | break; |
9237 | 0 | case 2: /* peer-vmac */ |
9238 | 0 | offset = fOctetString(tvb, pinfo, tree, offset, "peer-vmac: ", lvt); |
9239 | 0 | break; |
9240 | 0 | case 3: /* peer-uuid */ |
9241 | 0 | offset = fOctetString(tvb, pinfo, tree, offset, "peer-uuid: ", lvt); |
9242 | 0 | break; |
9243 | 0 | case 4: /* error */ |
9244 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9245 | 0 | offset = fError(tvb, pinfo, tree, offset); |
9246 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9247 | 0 | break; |
9248 | 0 | case 5: /* details - OPTIONAL */ |
9249 | 0 | offset = fCharacterString(tvb, pinfo, tree, offset, "details: "); |
9250 | 0 | break; |
9251 | 0 | default: |
9252 | 0 | return offset; |
9253 | 0 | } |
9254 | 0 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
9255 | 0 | } |
9256 | 0 | return offset; |
9257 | 0 | } |
9258 | | |
9259 | | /** |
9260 | | * BACnetSCHubConnection ::= SEQUENCE { |
9261 | | * connection-state [0] BACnetSCConnectionState, |
9262 | | * connect-timestamp [1] BACnetDateTime, |
9263 | | * disconnect-timestamp [2] BACnetDateTime, |
9264 | | * error [3] Error OPTIONAL |
9265 | | * error-details [4] CharacterString OPTIONAL |
9266 | | * } |
9267 | | * @param tvb the tv buffer of the current data |
9268 | | * @param pinfo the packet info of the current data |
9269 | | * @param tree the tree to append this item to |
9270 | | * @param offset the offset in the tvb |
9271 | | * @return modified offset |
9272 | | */ |
9273 | | static unsigned |
9274 | | fSCHubConnection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
9275 | 0 | { |
9276 | 0 | unsigned lastoffset = 0; |
9277 | 0 | uint8_t tag_no, tag_info; |
9278 | 0 | uint32_t lvt; |
9279 | |
|
9280 | 0 | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
9281 | 0 | lastoffset = offset; |
9282 | | /* check the tag. A closing tag means we are done */ |
9283 | 0 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
9284 | 0 | if (tag_is_closing(tag_info)) { |
9285 | 0 | return offset; |
9286 | 0 | } |
9287 | 0 | switch (tag_no) { |
9288 | 0 | case 0: /* connection-state */ |
9289 | 0 | offset = fEnumeratedTag(tvb, pinfo, tree, offset, "connection-state: ", BACnetSCConnectionState); |
9290 | 0 | break; |
9291 | 0 | case 1: /* connect-timestamp */ |
9292 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9293 | 0 | offset = fDateTime(tvb, pinfo, tree, offset, "connect-timestamp: "); |
9294 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9295 | 0 | break; |
9296 | 0 | case 2: /* disconnect-timestamp */ |
9297 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9298 | 0 | offset = fDateTime(tvb, pinfo, tree, offset, "disconnect-timestamp: "); |
9299 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9300 | 0 | break; |
9301 | 0 | case 3: /* error */ |
9302 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9303 | 0 | offset = fError(tvb, pinfo, tree, offset); |
9304 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9305 | 0 | break; |
9306 | 0 | case 4: /* details - OPTIONAL */ |
9307 | 0 | offset = fCharacterString(tvb, pinfo, tree, offset, "details: "); |
9308 | 0 | break; |
9309 | 0 | default: |
9310 | 0 | return offset; |
9311 | 0 | } |
9312 | 0 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
9313 | 0 | } |
9314 | 0 | return offset; |
9315 | 0 | } |
9316 | | |
9317 | | /** |
9318 | | * BACnetSCHubFunctionConnection ::= SEQUENCE { |
9319 | | * connection-state [0] BACnetSCConnectionState, |
9320 | | * connect-timestamp [1] BACnetDateTime, |
9321 | | * disconnect-timestamp [2] BACnetDateTime, |
9322 | | * peer-address [3] BACnetHostNPort, |
9323 | | * peer-vmac [4] OCTET STRING (SIZE(6)) |
9324 | | * peer-uuid [5] OCTET STRING (SIZE(16)) |
9325 | | * error [6] Error OPTIONAL |
9326 | | * error-details [7] CharacterString OPTIONAL |
9327 | | * } |
9328 | | * @param tvb the tv buffer of the current data |
9329 | | * @param pinfo the packet info of the current data |
9330 | | * @param tree the tree to append this item to |
9331 | | * @param offset the offset in the tvb |
9332 | | * @return modified offset |
9333 | | */ |
9334 | | static unsigned |
9335 | | fSCHubFunctionConnection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
9336 | 40 | { |
9337 | 40 | unsigned lastoffset = 0; |
9338 | 40 | uint8_t tag_no, tag_info; |
9339 | 40 | uint32_t lvt; |
9340 | | |
9341 | 634 | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
9342 | 633 | lastoffset = offset; |
9343 | | /* check the tag. A closing tag means we are done */ |
9344 | 633 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
9345 | 633 | if (tag_is_closing(tag_info)) { |
9346 | 7 | return offset; |
9347 | 7 | } |
9348 | 626 | switch (tag_no) { |
9349 | 258 | case 0: /* connection-state */ |
9350 | 258 | offset = fEnumeratedTag(tvb, pinfo, tree, offset, "connection-state: ", BACnetSCConnectionState); |
9351 | 258 | break; |
9352 | 9 | case 1: /* connect-timestamp */ |
9353 | 9 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9354 | 9 | offset = fDateTime(tvb, pinfo, tree, offset, "connect-timestamp: "); |
9355 | 9 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9356 | 9 | break; |
9357 | 23 | case 2: /* disconnect-timestamp */ |
9358 | 23 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9359 | 23 | offset = fDateTime(tvb, pinfo, tree, offset, "disconnect-timestamp: "); |
9360 | 23 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9361 | 23 | break; |
9362 | 77 | case 3: /* peer-address */ |
9363 | 77 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9364 | 77 | offset = fHostNPort(tvb, pinfo, tree, offset,"peer-address: "); |
9365 | 77 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9366 | 77 | break; |
9367 | 43 | case 4: /* peer-vmac */ |
9368 | 43 | offset = fOctetString(tvb, pinfo, tree, offset, "peer-vmac: ", lvt); |
9369 | 43 | break; |
9370 | 26 | case 5: /* peer-uuid */ |
9371 | 26 | offset = fOctetString(tvb, pinfo, tree, offset, "peer-uuid: ", lvt); |
9372 | 26 | break; |
9373 | 47 | case 6: /* error */ |
9374 | 47 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9375 | 47 | offset = fError(tvb, pinfo, tree, offset); |
9376 | 47 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9377 | 47 | break; |
9378 | 115 | case 7: /* details - OPTIONAL */ |
9379 | 115 | offset = fCharacterString(tvb, pinfo, tree, offset, "details: "); |
9380 | 115 | break; |
9381 | 28 | default: |
9382 | 28 | return offset; |
9383 | 626 | } |
9384 | 594 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
9385 | 594 | } |
9386 | 1 | return offset; |
9387 | 40 | } |
9388 | | |
9389 | | static unsigned |
9390 | | fWeeklySchedule(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
9391 | 26 | { |
9392 | 26 | unsigned lastoffset = 0; |
9393 | 26 | uint8_t tag_no, tag_info; |
9394 | 26 | uint32_t lvt; |
9395 | 26 | unsigned i = 1; /* day of week array index */ |
9396 | 26 | proto_tree *subtree = tree; |
9397 | | |
9398 | 26 | if (propertyArrayIndex > 0) { |
9399 | | /* BACnetARRAY index 0 refers to the length |
9400 | | of the array, not the elements of the array. |
9401 | | BACnetARRAY index -1 is our internal flag that |
9402 | | the optional index was not used. |
9403 | | BACnetARRAY refers to this as all elements of the array. |
9404 | | If the optional index is specified for a BACnetARRAY, |
9405 | | then that specific array element is referenced. */ |
9406 | 1 | i = propertyArrayIndex; |
9407 | 1 | } |
9408 | 38 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
9409 | 38 | lastoffset = offset; |
9410 | 38 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
9411 | 38 | if (tag_is_closing(tag_info)) { |
9412 | 0 | return offset; /* outer encoding will print out closing tag */ |
9413 | 0 | } |
9414 | 38 | subtree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_bacapp_value, NULL, |
9415 | 38 | val_to_str(pinfo->pool, i++, day_of_week, "day of week (%d) not found")); |
9416 | 38 | offset = fDailySchedule(tvb, pinfo, subtree, offset); |
9417 | 38 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
9418 | 38 | } |
9419 | 26 | return offset; |
9420 | 26 | } |
9421 | | |
9422 | | |
9423 | | static unsigned |
9424 | | fUTCTimeSynchronizationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
9425 | 2 | { |
9426 | 2 | if (tvb_reported_length_remaining(tvb, offset) <= 0) |
9427 | 0 | return offset; |
9428 | | |
9429 | 2 | return fDateTime(tvb, pinfo, tree, offset, "UTC-Time: "); |
9430 | 2 | } |
9431 | | |
9432 | | static unsigned |
9433 | | fTimeSynchronizationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
9434 | 3 | { |
9435 | 3 | if (tvb_reported_length_remaining(tvb, offset) <= 0) |
9436 | 0 | return offset; |
9437 | | |
9438 | 3 | return fDateTime(tvb, pinfo, tree, offset, NULL); |
9439 | 3 | } |
9440 | | |
9441 | | static unsigned |
9442 | | fWriteGroupRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
9443 | 242 | { |
9444 | 242 | unsigned lastoffset = 0, len; |
9445 | 242 | uint8_t tag_no, tag_info; |
9446 | 242 | uint32_t lvt; |
9447 | 242 | proto_tree *subtree = tree; |
9448 | | |
9449 | 4.33k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
9450 | 4.27k | lastoffset = offset; |
9451 | 4.27k | len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
9452 | 4.27k | if (tag_is_closing(tag_info)) { |
9453 | 1.27k | offset += len; |
9454 | 1.27k | subtree = tree; |
9455 | 1.27k | continue; |
9456 | 1.27k | } |
9457 | | |
9458 | 2.99k | switch (tag_no) { |
9459 | 1.62k | case 0: /* group-number */ |
9460 | 1.62k | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "Group number: "); |
9461 | 1.62k | break; |
9462 | 504 | case 1: /* write-priority */ |
9463 | 504 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "Priority: "); |
9464 | 504 | break; |
9465 | 283 | case 2: /* change-list */ |
9466 | 283 | if (tag_is_opening(tag_info)) { |
9467 | 272 | subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "change-list: "); |
9468 | 272 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
9469 | | |
9470 | 10.4k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
9471 | 10.4k | lastoffset = offset; |
9472 | 10.4k | len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
9473 | 10.4k | if (tag_is_closing(tag_info)) { |
9474 | 132 | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
9475 | 132 | offset += len; |
9476 | 132 | subtree = tree; |
9477 | 132 | break; |
9478 | 132 | } |
9479 | | |
9480 | 10.2k | switch (tag_no) { |
9481 | 4.16k | case 0: /* channel */ |
9482 | 4.16k | if (tag_info && ! tag_is_opening(tag_info)) { |
9483 | | /* context tagged */ |
9484 | 386 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "Channel: "); |
9485 | 3.78k | } else { |
9486 | | /* application tagged */ |
9487 | 3.78k | offset = fChannelValue(tvb, pinfo, subtree, offset, "Value: "); |
9488 | 3.78k | } |
9489 | 4.16k | break; |
9490 | 1.35k | case 1: /* overriding-priority */ |
9491 | 1.35k | if (tag_info && ! tag_is_opening(tag_info)) { |
9492 | | /* context tagged */ |
9493 | 428 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "Overriding priority: "); |
9494 | 930 | } else { |
9495 | | /* application tagged */ |
9496 | 930 | offset = fChannelValue(tvb, pinfo, subtree, offset, "Value: "); |
9497 | 930 | } |
9498 | 1.35k | break; |
9499 | 4.74k | default: /* channel-value (application tagged, or opening/closing context-0 tagged) */ |
9500 | 4.74k | offset = fChannelValue(tvb, pinfo, subtree, offset, "Value: "); |
9501 | 4.74k | break; |
9502 | 10.2k | } |
9503 | 10.2k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
9504 | 10.2k | } |
9505 | 272 | } |
9506 | 11 | else { |
9507 | 11 | expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag); |
9508 | 11 | } |
9509 | 208 | break; |
9510 | 501 | case 3: /* inhibit-delay */ |
9511 | 501 | offset = fBooleanTag(tvb, pinfo, tree, offset, "Inhibit delay: "); |
9512 | 501 | break; |
9513 | 75 | default: |
9514 | 75 | return offset; |
9515 | 2.99k | } |
9516 | 2.84k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
9517 | 2.84k | } |
9518 | 87 | return offset; |
9519 | 242 | } |
9520 | | |
9521 | | static unsigned |
9522 | | fDateRange(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
9523 | 166 | { |
9524 | 166 | if (tvb_reported_length_remaining(tvb, offset) <= 0) |
9525 | 0 | return offset; |
9526 | 166 | offset = fDate(tvb, pinfo, tree, offset, "Start Date: "); |
9527 | 166 | return fDate(tvb, pinfo, tree, offset, "End Date: "); |
9528 | 166 | } |
9529 | | |
9530 | | static unsigned |
9531 | | fVendorIdentifier(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
9532 | 4.29k | { |
9533 | 4.29k | uint32_t val = 0; |
9534 | 4.29k | uint8_t tag_no, tag_info; |
9535 | 4.29k | uint32_t lvt; |
9536 | 4.29k | unsigned tag_len; |
9537 | 4.29k | proto_item *ti; |
9538 | 4.29k | proto_tree *subtree; |
9539 | 4.29k | static const char *label = "Vendor ID"; |
9540 | | |
9541 | 4.29k | tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
9542 | 4.29k | if (fUnsigned32(tvb, offset + tag_len, lvt, &val)) |
9543 | 1.53k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, |
9544 | 1.53k | ett_bacapp_tag, &ti, "%s: %s (%u)", |
9545 | 1.53k | label, |
9546 | 1.53k | val_to_str_ext_const(val, &BACnetVendorIdentifiers_ext, "Unknown Vendor"), |
9547 | 1.53k | val); |
9548 | 2.75k | else |
9549 | 2.75k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, |
9550 | 2.75k | ett_bacapp_tag, &ti, "%s - %u octets (Unsigned)", label, lvt); |
9551 | 4.29k | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
9552 | | |
9553 | 4.29k | if ((lvt < 1) || (lvt > 2)) { /* vendorIDs >= 1 and <= 2 are supported */ |
9554 | 3.14k | expert_add_info_format(pinfo, ti, &ei_bacapp_bad_length, |
9555 | 3.14k | "Wrong length indicated. Expected 1 or 2, got %u", lvt); |
9556 | 3.14k | return offset+tag_len+lvt; |
9557 | 3.14k | } |
9558 | | |
9559 | 1.14k | proto_tree_add_item(subtree, hf_BACnetVendorIdentifier, tvb, |
9560 | 1.14k | offset+tag_len, lvt, ENC_BIG_ENDIAN); |
9561 | | |
9562 | 1.14k | return offset+tag_len+lvt; |
9563 | 4.29k | } |
9564 | | |
9565 | | static unsigned |
9566 | | fRestartReason(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
9567 | 1.77k | { |
9568 | 1.77k | uint32_t val = 0; |
9569 | 1.77k | uint8_t tag_no, tag_info; |
9570 | 1.77k | uint32_t lvt; |
9571 | 1.77k | unsigned tag_len; |
9572 | 1.77k | proto_item *ti; |
9573 | 1.77k | proto_tree *subtree; |
9574 | 1.77k | static const char *label = "Restart Reason"; |
9575 | | |
9576 | 1.77k | tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
9577 | 1.77k | if (fUnsigned32(tvb, offset + tag_len, lvt, &val)) |
9578 | 811 | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, |
9579 | 811 | ett_bacapp_tag, &ti, "%s: %s (%u)", label, |
9580 | 811 | val_to_str_const(val, BACnetRestartReason, "Unknown reason"), val); |
9581 | 963 | else |
9582 | 963 | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, |
9583 | 963 | ett_bacapp_tag, &ti, "%s - %u octets (Unsigned)", label, lvt); |
9584 | 1.77k | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
9585 | | |
9586 | 1.77k | if (lvt != 1) { |
9587 | 1.50k | expert_add_info_format(pinfo, ti, &ei_bacapp_bad_length, |
9588 | 1.50k | "Wrong length indicated. Expected 1, got %u", lvt); |
9589 | 1.50k | return offset+tag_len+lvt; |
9590 | 1.50k | } |
9591 | | |
9592 | 269 | proto_tree_add_item(subtree, hf_BACnetRestartReason, tvb, |
9593 | 269 | offset+tag_len, lvt, ENC_BIG_ENDIAN); |
9594 | | |
9595 | 269 | return offset+tag_len+lvt; |
9596 | 1.77k | } |
9597 | | |
9598 | | static unsigned |
9599 | | fConfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
9600 | 64 | { |
9601 | 64 | uint8_t tag_no, tag_info; |
9602 | 64 | uint32_t lvt; |
9603 | 64 | unsigned lastoffset = 0; |
9604 | | |
9605 | 1.21k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
9606 | 1.20k | lastoffset = offset; |
9607 | 1.20k | switch (fTagNo(tvb, offset)) { |
9608 | 463 | case 0: /* textMessageSourceDevice */ |
9609 | 463 | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_device_identifier); |
9610 | 463 | break; |
9611 | 482 | case 1: /* messageClass */ |
9612 | 482 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9613 | 482 | switch (fTagNo(tvb, offset)) { |
9614 | 21 | case 0: /* numeric */ |
9615 | 21 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "message Class: "); |
9616 | 21 | break; |
9617 | 418 | case 1: /* character */ |
9618 | 418 | offset = fCharacterString(tvb, pinfo, tree, offset, "message Class: "); |
9619 | 418 | break; |
9620 | 482 | } |
9621 | 480 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9622 | 480 | break; |
9623 | 146 | case 2: /* messagePriority */ |
9624 | 146 | offset = fEnumeratedTag(tvb, pinfo, tree, offset, "message Priority: ", |
9625 | 146 | BACnetMessagePriority); |
9626 | 146 | break; |
9627 | 70 | case 3: /* message */ |
9628 | 70 | offset = fCharacterString(tvb, pinfo, tree, offset, "message: "); |
9629 | 70 | break; |
9630 | 46 | default: |
9631 | 46 | return offset; |
9632 | 1.20k | } |
9633 | 1.15k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
9634 | 1.15k | } |
9635 | 8 | return offset; |
9636 | 64 | } |
9637 | | |
9638 | | static unsigned |
9639 | | fUnconfirmedTextMessageRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
9640 | 6 | { |
9641 | 6 | return fConfirmedTextMessageRequest(tvb, pinfo, tree, offset); |
9642 | 6 | } |
9643 | | |
9644 | | static unsigned |
9645 | | fConfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
9646 | 88 | { |
9647 | 88 | unsigned lastoffset, len; |
9648 | 88 | uint8_t tag_no, tag_info; |
9649 | 88 | uint32_t lvt; |
9650 | 88 | proto_tree *subtree = tree; |
9651 | 88 | tvbuff_t *next_tvb; |
9652 | 88 | unsigned vendor_identifier = 0; |
9653 | 88 | unsigned service_number = 0; |
9654 | | |
9655 | 88 | len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
9656 | 88 | fUnsigned32(tvb, offset+len, lvt, &vendor_identifier); |
9657 | 88 | col_append_fstr(pinfo->cinfo, COL_INFO, "V=%u ", vendor_identifier); |
9658 | 88 | offset = fVendorIdentifier(tvb, pinfo, subtree, offset); |
9659 | | |
9660 | 88 | next_tvb = tvb_new_subset_remaining(tvb, offset); |
9661 | 88 | if (dissector_try_uint(bacapp_dissector_table, |
9662 | 88 | vendor_identifier, next_tvb, pinfo, tree)) { |
9663 | | /* we parsed it so skip over length and we are done */ |
9664 | 0 | offset += tvb_reported_length(next_tvb); |
9665 | 0 | return offset; |
9666 | 0 | } |
9667 | | |
9668 | | /* Not handled by vendor dissector */ |
9669 | | |
9670 | | /* exit loop if nothing happens inside */ |
9671 | 342 | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
9672 | 330 | lastoffset = offset; |
9673 | 330 | len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
9674 | 330 | if (tag_is_closing(tag_info)) { |
9675 | 10 | if (tag_no == 2) { /* Make sure it's the expected tag */ |
9676 | 3 | offset += len; |
9677 | 3 | subtree = tree; |
9678 | 3 | continue; |
9679 | 7 | } else { |
9680 | 7 | break; /* End loop if incorrect closing tag */ |
9681 | 7 | } |
9682 | 10 | } |
9683 | 320 | switch (tag_no) { |
9684 | | |
9685 | | /* vendorID is now parsed above */ |
9686 | 247 | case 1: /* serviceNumber */ |
9687 | 247 | fUnsigned32(tvb, offset+len, lvt, &service_number); |
9688 | 247 | col_append_fstr(pinfo->cinfo, COL_INFO, "SN=%u ", service_number); |
9689 | 247 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "service Number: "); |
9690 | 247 | break; |
9691 | 13 | case 2: /*serviceParameters */ |
9692 | 13 | if (tag_is_opening(tag_info)) { |
9693 | 8 | subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, |
9694 | 8 | ett_bacapp_value, NULL, "service Parameters"); |
9695 | 8 | propertyIdentifier = -1; |
9696 | 8 | offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset); |
9697 | 8 | } else { |
9698 | 5 | expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag); |
9699 | 5 | } |
9700 | 13 | break; |
9701 | 60 | default: |
9702 | 60 | return offset; |
9703 | 320 | } |
9704 | 256 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
9705 | 256 | } |
9706 | | |
9707 | 24 | return offset; |
9708 | 88 | } |
9709 | | |
9710 | | static unsigned |
9711 | | fUnconfirmedPrivateTransferRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
9712 | 6 | { |
9713 | 6 | return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset); |
9714 | 6 | } |
9715 | | |
9716 | | static unsigned |
9717 | | fConfirmedPrivateTransferAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
9718 | 4 | { |
9719 | 4 | return fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset); |
9720 | 4 | } |
9721 | | |
9722 | | static unsigned |
9723 | | fLifeSafetyOperationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *label) |
9724 | 50 | { |
9725 | 50 | unsigned lastoffset = 0; |
9726 | 50 | uint8_t tag_no, tag_info; |
9727 | 50 | uint32_t lvt; |
9728 | 50 | proto_tree *subtree = tree; |
9729 | | |
9730 | 50 | if (label != NULL) { |
9731 | 0 | subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, label); |
9732 | 0 | } |
9733 | | |
9734 | 1.38k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
9735 | 1.37k | lastoffset = offset; |
9736 | 1.37k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
9737 | | |
9738 | 1.37k | switch (tag_no) { |
9739 | 788 | case 0: /* subscriberProcessId */ |
9740 | 788 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "requesting Process Id: "); |
9741 | 788 | break; |
9742 | 271 | case 1: /* requestingSource */ |
9743 | 271 | offset = fCharacterString(tvb, pinfo, tree, offset, "requesting Source: "); |
9744 | 271 | break; |
9745 | 159 | case 2: /* request */ |
9746 | 159 | offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset, |
9747 | 159 | "request: ", BACnetLifeSafetyOperation, 64); |
9748 | 159 | break; |
9749 | 120 | case 3: /* objectId */ |
9750 | 120 | offset = fObjectIdentifier(tvb, pinfo, subtree, offset, hf_bacapp_object_identifier); |
9751 | 120 | break; |
9752 | 30 | default: |
9753 | 30 | return offset; |
9754 | 1.37k | } |
9755 | 1.33k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
9756 | 1.33k | } |
9757 | 11 | return offset; |
9758 | 50 | } |
9759 | | |
9760 | | typedef struct _value_string_enum { |
9761 | | uint8_t tag_no; |
9762 | | const value_string *valstr; |
9763 | | } value_string_enum; |
9764 | | |
9765 | | static const value_string_enum |
9766 | | BACnetPropertyStatesEnums[] = { |
9767 | | { 1, BACnetBinaryPV }, |
9768 | | { 2, BACnetEventType }, |
9769 | | { 3, BACnetPolarity }, |
9770 | | { 4, BACnetProgramRequest }, |
9771 | | { 5, BACnetProgramState }, |
9772 | | { 6, BACnetProgramError }, |
9773 | | { 7, BACnetReliability }, |
9774 | | { 8, BACnetEventState }, |
9775 | | { 9, BACnetDeviceStatus }, |
9776 | | { 10, BACnetEngineeringUnits }, |
9777 | | { 12, BACnetLifeSafetyMode }, |
9778 | | { 13, BACnetLifeSafetyState }, |
9779 | | { 14, BACnetRestartReason }, |
9780 | | { 15, BACnetDoorAlarmState }, |
9781 | | { 16, BACnetAction }, |
9782 | | { 17, BACnetDoorSecuredStatus }, |
9783 | | { 18, BACnetDoorStatus }, |
9784 | | { 19, BACnetDoorValue }, |
9785 | | { 20, BACnetFileAccessMethod }, |
9786 | | { 21, BACnetLockStatus }, |
9787 | | { 22, BACnetLifeSafetyOperation }, |
9788 | | { 23, BACnetMaintenance }, |
9789 | | { 24, BACnetNodeType }, |
9790 | | { 25, BACnetNotifyType }, |
9791 | | { 26, BACnetSecurityLevel }, |
9792 | | { 27, BACnetShedState }, |
9793 | | { 28, BACnetSilencedState }, |
9794 | | { 30, BACnetAccessEvent }, |
9795 | | { 31, BACnetAccessZoneOccupancyState }, |
9796 | | { 32, BACnetAccessCredentialDisableReason }, |
9797 | | { 33, BACnetAccessCredentialDisable }, |
9798 | | { 34, BACnetAuthenticationStatus }, |
9799 | | { 36, BACnetBackupState }, |
9800 | | { 37, BACnetWriteStatus }, |
9801 | | { 38, BACnetLightingInProgress }, |
9802 | | { 39, BACnetLightingOperation }, |
9803 | | { 40, BACnetLightingTransition }, |
9804 | | { 42, BACnetBinaryLightingPV }, |
9805 | | { 43, BACnetTimerState }, |
9806 | | { 44, BACnetTimerTransition }, |
9807 | | { 45, BACnetIpMode }, |
9808 | | { 46, BACnetNetworkPortCommand }, |
9809 | | { 47, BACnetNetworkType }, |
9810 | | { 48, BACnetNetworkNumberQuality }, |
9811 | | { 49, BACnetEscalatorOperationDirection }, |
9812 | | { 50, BACnetEscalatorFault }, |
9813 | | { 51, BACnetEscalatorMode }, |
9814 | | { 52, BACnetLiftCarDirection }, |
9815 | | { 53, BACnetLiftCarDoorCommand }, |
9816 | | { 54, BACnetLiftCarDriveStatus }, |
9817 | | { 55, BACnetLiftCarMode }, |
9818 | | { 56, BACnetLiftGroupMode }, |
9819 | | { 57, BACnetLiftFault }, |
9820 | | { 58, BACnetProtocolLevel }, |
9821 | | { 59, BACnetAuditLevel }, |
9822 | | { 60, BACnetAuditOperation } |
9823 | | }; |
9824 | 44.9k | #define BACnetPropertyStatesEnums_Size array_length(BACnetPropertyStatesEnums) |
9825 | | |
9826 | | static unsigned |
9827 | | fBACnetPropertyStates(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
9828 | 9.50k | { |
9829 | 9.50k | uint8_t tag_no, tag_info; |
9830 | 9.50k | uint32_t lvt; |
9831 | 9.50k | uint32_t idx; |
9832 | 9.50k | const char* label; |
9833 | 9.50k | const value_string_enum* valstrenum; |
9834 | | |
9835 | 9.50k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
9836 | 9.50k | label = wmem_strdup_printf(pinfo->pool, "%s: ", |
9837 | 9.50k | val_to_str_const( tag_no, VALS(BACnetPropertyStates), "Unknown State" )); |
9838 | | |
9839 | 9.50k | switch (tag_no) { |
9840 | 3.91k | case 0: |
9841 | 3.91k | offset = fBooleanTag(tvb, pinfo, tree, offset, label); |
9842 | 3.91k | break; |
9843 | 417 | case 11: |
9844 | 417 | offset = fUnsignedTag(tvb, pinfo, tree, offset, label); |
9845 | 417 | break; |
9846 | 6 | case 41: |
9847 | 6 | offset = fSignedTag(tvb, pinfo, tree, offset, label); |
9848 | 6 | break; |
9849 | 9 | case 63: |
9850 | 9 | offset = fUnsignedTag(tvb, pinfo, tree, offset, label); |
9851 | 9 | break; |
9852 | 5.16k | default: |
9853 | 5.16k | valstrenum = NULL; |
9854 | | |
9855 | 44.9k | for (idx = 0; idx < BACnetPropertyStatesEnums_Size; idx++) { |
9856 | 44.6k | valstrenum = &BACnetPropertyStatesEnums[idx]; |
9857 | 44.6k | if (valstrenum->tag_no == tag_no && |
9858 | 4.79k | valstrenum->valstr != NULL) { |
9859 | 4.79k | break; |
9860 | 4.79k | } |
9861 | 39.8k | valstrenum = NULL; |
9862 | 39.8k | } |
9863 | | |
9864 | 5.16k | if (valstrenum == NULL) |
9865 | 368 | { |
9866 | 368 | offset = fEnumeratedTag(tvb, pinfo, tree, offset, label, NULL); |
9867 | | /* don't use Abstract type here because it is context tagged and therefore we don't know app type */ |
9868 | 368 | } |
9869 | 4.79k | else |
9870 | 4.79k | { |
9871 | 4.79k | offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset, label, |
9872 | 4.79k | VALS(valstrenum->valstr), 64); |
9873 | 4.79k | } |
9874 | 5.16k | break; |
9875 | 9.50k | } |
9876 | 9.48k | return offset; |
9877 | 9.50k | } |
9878 | | |
9879 | | |
9880 | | /* |
9881 | | BACnetDeviceObjectPropertyValue ::= SEQUENCE { |
9882 | | deviceIdentifier [0] BACnetObjectIdentifier, |
9883 | | objectIdentifier [1] BACnetObjectIdentifier, |
9884 | | propertyIdentifier [2] BACnetPropertyIdentifier, |
9885 | | arrayIndex [3] Unsigned OPTIONAL, |
9886 | | value [4] ABSTRACT-SYNTAX.&Type |
9887 | | } |
9888 | | */ |
9889 | | static unsigned |
9890 | | // NOLINTNEXTLINE(misc-no-recursion) |
9891 | | fDeviceObjectPropertyValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
9892 | 391 | { |
9893 | 391 | unsigned lastoffset = 0; |
9894 | 391 | uint8_t tag_no, tag_info; |
9895 | 391 | uint32_t lvt; |
9896 | | |
9897 | 1.25k | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
9898 | 1.24k | lastoffset = offset; |
9899 | | /* check the tag. A closing tag means we are done */ |
9900 | 1.24k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
9901 | 1.24k | if (tag_is_closing(tag_info)) { |
9902 | 20 | return offset; |
9903 | 20 | } |
9904 | 1.22k | switch (tag_no) { |
9905 | 479 | case 0: /* deviceIdentifier */ |
9906 | 479 | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_device_identifier); |
9907 | 479 | break; |
9908 | 84 | case 1: /* objectIdentifier */ |
9909 | 84 | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_object_identifier); |
9910 | 84 | break; |
9911 | 238 | case 2: /* propertyIdentifier */ |
9912 | 238 | offset = fPropertyIdentifier(tvb, pinfo, tree, offset); |
9913 | 238 | break; |
9914 | 82 | case 3: /* arrayIndex - OPTIONAL */ |
9915 | 82 | offset = fUnsignedTag(tvb, pinfo, tree, offset, |
9916 | 82 | "arrayIndex: "); |
9917 | 82 | break; |
9918 | 220 | case 4: /* value */ |
9919 | 220 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9920 | 220 | offset = fAbstractSyntaxNType(tvb, pinfo, tree, offset); |
9921 | 220 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
9922 | 220 | break; |
9923 | 124 | default: |
9924 | 124 | return offset; |
9925 | 1.22k | } |
9926 | 1.09k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
9927 | 1.09k | } |
9928 | 234 | return offset; |
9929 | 391 | } |
9930 | | |
9931 | | /* |
9932 | | BACnetDeviceObjectPropertyReference ::= SEQUENCE { |
9933 | | objectIdentifier [0] BACnetObjectIdentifier, |
9934 | | propertyIdentifier [1] BACnetPropertyIdentifier, |
9935 | | propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype |
9936 | | -- if omitted with an array then |
9937 | | -- the entire array is referenced |
9938 | | deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL |
9939 | | } |
9940 | | */ |
9941 | | static unsigned |
9942 | | fObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
9943 | 38 | { |
9944 | 38 | return fDeviceObjectPropertyReference(tvb, pinfo, tree, offset); |
9945 | 38 | } |
9946 | | |
9947 | | /* |
9948 | | BACnetDeviceObjectPropertyReference ::= SEQUENCE { |
9949 | | objectIdentifier [0] BACnetObjectIdentifier, |
9950 | | propertyIdentifier [1] BACnetPropertyIdentifier, |
9951 | | propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype |
9952 | | -- if omitted with an array then |
9953 | | -- the entire array is referenced |
9954 | | deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL |
9955 | | } |
9956 | | */ |
9957 | | static unsigned |
9958 | | // NOLINTNEXTLINE(misc-no-recursion) |
9959 | | fDeviceObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
9960 | 2.83k | { |
9961 | 2.83k | unsigned lastoffset = 0; |
9962 | 2.83k | uint8_t tag_no, tag_info; |
9963 | 2.83k | uint32_t lvt; |
9964 | | |
9965 | 7.20k | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
9966 | 7.17k | lastoffset = offset; |
9967 | | /* check the tag. A closing tag means we are done */ |
9968 | 7.17k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
9969 | 7.17k | if (tag_is_closing(tag_info)) { |
9970 | 771 | return offset; |
9971 | 771 | } |
9972 | 6.40k | switch (tag_no) { |
9973 | 1.83k | case 0: /* objectIdentifier */ |
9974 | 1.83k | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_object_identifier); |
9975 | 1.83k | break; |
9976 | 2.24k | case 1: /* propertyIdentifier */ |
9977 | 2.24k | offset = fPropertyIdentifier(tvb, pinfo, tree, offset); |
9978 | 2.24k | break; |
9979 | 750 | case 2: /* arrayIndex - OPTIONAL */ |
9980 | 750 | offset = fUnsignedTag(tvb, pinfo, tree, offset, |
9981 | 750 | "arrayIndex: "); |
9982 | 750 | break; |
9983 | 420 | case 3: /* deviceIdentifier - OPTIONAL */ |
9984 | 420 | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_device_identifier); |
9985 | 420 | break; |
9986 | 1.15k | default: |
9987 | 1.15k | return offset; |
9988 | 6.40k | } |
9989 | 5.22k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
9990 | 5.22k | } |
9991 | 879 | return offset; |
9992 | 2.83k | } |
9993 | | |
9994 | | static unsigned |
9995 | | // NOLINTNEXTLINE(misc-no-recursion) |
9996 | | fNotificationParameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
9997 | 5.67k | { |
9998 | 5.67k | unsigned lastoffset = offset; |
9999 | 5.67k | uint8_t tag_no, tag_info; |
10000 | 5.67k | uint32_t lvt; |
10001 | 5.67k | proto_tree *subtree = tree; |
10002 | 5.67k | proto_tree *pvtree; |
10003 | | |
10004 | 5.67k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
10005 | 5.67k | subtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0, |
10006 | 5.67k | ett_bacapp_value, NULL, "notification parameters (%d) %s", |
10007 | 5.67k | tag_no, val_to_str_const(tag_no, BACnetEventType, "invalid type")); |
10008 | | /* Opening tag for parameter choice */ |
10009 | 5.67k | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10010 | | |
10011 | 5.67k | switch (tag_no) { |
10012 | 319 | case 0: /* change-of-bitstring */ |
10013 | 579 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
10014 | 572 | lastoffset = offset; |
10015 | 572 | switch (fTagNo(tvb, offset)) { |
10016 | 299 | case 0: |
10017 | 299 | offset = fBitStringTag(tvb, pinfo, subtree, offset, |
10018 | 299 | "referenced-bitstring: "); |
10019 | 299 | break; |
10020 | 36 | case 1: |
10021 | 36 | offset = fBitStringTagVS(tvb, pinfo, subtree, offset, |
10022 | 36 | "status-flags: ", BACnetStatusFlags); |
10023 | 36 | lastoffset = offset; |
10024 | 36 | break; |
10025 | 237 | default: |
10026 | 237 | break; |
10027 | 572 | } |
10028 | 531 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
10029 | 531 | } |
10030 | 278 | break; |
10031 | 278 | case 1: /* change-of-state */ |
10032 | 342 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
10033 | 336 | lastoffset = offset; |
10034 | 336 | switch (fTagNo(tvb, offset)) { |
10035 | 238 | case 0: |
10036 | 238 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10037 | 238 | offset = fBACnetPropertyStates(tvb, pinfo, subtree, offset); |
10038 | 238 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10039 | 238 | break; |
10040 | 33 | case 1: |
10041 | 33 | offset = fBitStringTagVS(tvb, pinfo, subtree, offset, |
10042 | 33 | "status-flags: ", BACnetStatusFlags); |
10043 | 33 | lastoffset = offset; |
10044 | 33 | break; |
10045 | 65 | default: |
10046 | 65 | break; |
10047 | 336 | } |
10048 | 330 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
10049 | 330 | } |
10050 | 103 | break; |
10051 | 218 | case 2: /* change-of-value */ |
10052 | 292 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
10053 | 289 | lastoffset = offset; |
10054 | 289 | switch (fTagNo(tvb, offset)) { |
10055 | 83 | case 0: |
10056 | 83 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10057 | 83 | switch (fTagNo(tvb, offset)) { |
10058 | 43 | case 0: |
10059 | 43 | offset = fBitStringTag(tvb, pinfo, subtree, offset, |
10060 | 43 | "changed-bits: "); |
10061 | 43 | break; |
10062 | 8 | case 1: |
10063 | 8 | offset = fRealTag(tvb, pinfo, subtree, offset, |
10064 | 8 | "changed-value: "); |
10065 | 8 | break; |
10066 | 32 | default: |
10067 | 32 | break; |
10068 | 83 | } |
10069 | 74 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10070 | 74 | break; |
10071 | 19 | case 1: |
10072 | 19 | offset = fBitStringTagVS(tvb, pinfo, subtree, offset, |
10073 | 19 | "status-flags: ", BACnetStatusFlags); |
10074 | 19 | lastoffset = offset; |
10075 | 19 | break; |
10076 | 187 | default: |
10077 | 187 | break; |
10078 | 289 | } |
10079 | 280 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
10080 | 280 | } |
10081 | 209 | break; |
10082 | 933 | case 3: /* command-failure */ |
10083 | 2.27k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
10084 | 2.26k | lastoffset = offset; |
10085 | 2.26k | switch (fTagNo(tvb, offset)) { |
10086 | 1.45k | case 0: /* "command-value: " */ |
10087 | | /* from BACnet Table 13-3, |
10088 | | Standard Object Property Values Returned in Notifications */ |
10089 | 1.45k | propertyIdentifier = 85; /* PRESENT_VALUE */ |
10090 | 1.45k | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10091 | 1.45k | offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset); |
10092 | 1.45k | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10093 | 1.45k | break; |
10094 | 221 | case 1: |
10095 | 221 | offset = fBitStringTagVS(tvb, pinfo, subtree, offset, |
10096 | 221 | "status-flags: ", BACnetStatusFlags); |
10097 | 221 | break; |
10098 | 76 | case 2: /* "feedback-value: " */ |
10099 | 76 | propertyIdentifier = 40; /* FEEDBACK_VALUE */ |
10100 | 76 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10101 | 76 | offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset); |
10102 | 76 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10103 | 76 | lastoffset = offset; |
10104 | 76 | break; |
10105 | 512 | default: |
10106 | 512 | break; |
10107 | 2.26k | } |
10108 | 1.89k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
10109 | 1.89k | } |
10110 | 565 | break; |
10111 | 565 | case 4: /* floating-limit */ |
10112 | 589 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
10113 | 586 | lastoffset = offset; |
10114 | 586 | switch (fTagNo(tvb, offset)) { |
10115 | 297 | case 0: |
10116 | 297 | offset = fRealTag(tvb, pinfo, subtree, offset, "reference-value: "); |
10117 | 297 | break; |
10118 | 110 | case 1: |
10119 | 110 | offset = fBitStringTagVS(tvb, pinfo, subtree, offset, |
10120 | 110 | "status-flags: ", BACnetStatusFlags); |
10121 | 110 | break; |
10122 | 77 | case 2: |
10123 | 77 | offset = fRealTag(tvb, pinfo, subtree, offset, "setpoint-value: "); |
10124 | 77 | break; |
10125 | 24 | case 3: |
10126 | 24 | offset = fRealTag(tvb, pinfo, subtree, offset, "error-limit: "); |
10127 | 24 | lastoffset = offset; |
10128 | 24 | break; |
10129 | 78 | default: |
10130 | 78 | break; |
10131 | 586 | } |
10132 | 581 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
10133 | 581 | } |
10134 | 103 | break; |
10135 | 108 | case 5: /* out-of-range */ |
10136 | 674 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
10137 | 670 | lastoffset = offset; |
10138 | 670 | switch (fTagNo(tvb, offset)) { |
10139 | 286 | case 0: |
10140 | 286 | offset = fRealTag(tvb, pinfo, subtree, offset, "exceeding-value: "); |
10141 | 286 | break; |
10142 | 208 | case 1: |
10143 | 208 | offset = fBitStringTagVS(tvb, pinfo, subtree, offset, |
10144 | 208 | "status-flags: ", BACnetStatusFlags); |
10145 | 208 | break; |
10146 | 80 | case 2: |
10147 | 80 | offset = fRealTag(tvb, pinfo, subtree, offset, "deadband: "); |
10148 | 80 | break; |
10149 | 32 | case 3: |
10150 | 32 | offset = fRealTag(tvb, pinfo, subtree, offset, "exceeded-limit: "); |
10151 | 32 | lastoffset = offset; |
10152 | 32 | break; |
10153 | 64 | default: |
10154 | 64 | break; |
10155 | 670 | } |
10156 | 661 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
10157 | 661 | } |
10158 | 99 | break; |
10159 | 1.10k | case 6: |
10160 | 2.11k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
10161 | 1.93k | lastoffset = offset; |
10162 | 1.93k | offset =fBACnetPropertyValue(tvb, pinfo, subtree, offset); |
10163 | 1.93k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
10164 | 1.93k | } |
10165 | 1.10k | break; |
10166 | 117 | case 7: /* deprecated (was 'buffer-ready', changed and moved to [10]) */ |
10167 | 851 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
10168 | 844 | lastoffset = offset; |
10169 | 844 | switch (fTagNo(tvb, offset)) { |
10170 | 323 | case 0: |
10171 | 323 | offset = fObjectIdentifier(tvb, pinfo, subtree, offset, hf_bacapp_device_identifier); /* buffer-device */ |
10172 | 323 | break; |
10173 | 217 | case 1: |
10174 | 217 | offset = fObjectIdentifier(tvb, pinfo, subtree, offset, hf_bacapp_object_identifier); /* buffer-object */ |
10175 | 217 | break; |
10176 | 203 | case 2: |
10177 | 203 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10178 | 203 | offset = fDateTime(tvb, pinfo, subtree, offset, "previous-notification: "); |
10179 | 203 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10180 | 203 | break; |
10181 | 19 | case 3: |
10182 | 19 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10183 | 19 | offset = fDateTime(tvb, pinfo, subtree, offset, "current-notification: "); |
10184 | 19 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10185 | 19 | lastoffset = offset; |
10186 | 19 | break; |
10187 | 82 | default: |
10188 | 82 | break; |
10189 | 844 | } |
10190 | 834 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
10191 | 834 | } |
10192 | 107 | break; |
10193 | 131 | case 8: /* change-of-life-safety */ |
10194 | 1.57k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
10195 | 1.56k | lastoffset = offset; |
10196 | 1.56k | switch (fTagNo(tvb, offset)) { |
10197 | 1.09k | case 0: |
10198 | 1.09k | offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset, |
10199 | 1.09k | "new-state: ", BACnetLifeSafetyState, 256); |
10200 | 1.09k | break; |
10201 | 223 | case 1: |
10202 | 223 | offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset, |
10203 | 223 | "new-mode: ", BACnetLifeSafetyMode, 256); |
10204 | 223 | break; |
10205 | 131 | case 2: |
10206 | 131 | offset = fBitStringTagVS(tvb, pinfo, subtree, offset, |
10207 | 131 | "status-flags: ", BACnetStatusFlags); |
10208 | 131 | break; |
10209 | 27 | case 3: |
10210 | 27 | offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset, |
10211 | 27 | "operation-expected: ", BACnetLifeSafetyOperation, 64); |
10212 | 27 | lastoffset = offset; |
10213 | 27 | break; |
10214 | 97 | default: |
10215 | 97 | break; |
10216 | 1.56k | } |
10217 | 1.56k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
10218 | 1.56k | } |
10219 | 128 | break; |
10220 | 192 | case 9: /* extended */ |
10221 | 1.05k | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
10222 | 1.05k | lastoffset = offset; |
10223 | 1.05k | switch (fTagNo(tvb, offset)) { |
10224 | 741 | case 0: |
10225 | 741 | offset = fVendorIdentifier(tvb, pinfo, subtree, offset); |
10226 | 741 | break; |
10227 | 121 | case 1: |
10228 | 121 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "extended-event-type: "); |
10229 | 121 | break; |
10230 | 121 | case 2: /* parameters */ |
10231 | 121 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10232 | | |
10233 | 2.48k | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
10234 | 2.44k | const unsigned param_lastoffset = offset; |
10235 | 2.44k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
10236 | 2.44k | if (tag_is_closing(tag_info)) |
10237 | 24 | { |
10238 | 24 | break; |
10239 | 24 | } |
10240 | | |
10241 | 2.41k | if (tag_is_opening(tag_info)) |
10242 | 391 | { |
10243 | 391 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10244 | 391 | offset = fDeviceObjectPropertyValue(tvb, pinfo, subtree, offset); |
10245 | 391 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10246 | 391 | } |
10247 | 2.02k | else |
10248 | 2.02k | { |
10249 | 2.02k | offset = fApplicationTypes(tvb, pinfo, subtree, offset, "parameters: "); |
10250 | 2.02k | } |
10251 | 2.41k | if (offset <= param_lastoffset) |
10252 | 57 | break; /* nothing happened, exit loop */ |
10253 | 2.41k | } |
10254 | | |
10255 | 121 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10256 | 121 | lastoffset = offset; |
10257 | 121 | break; |
10258 | 69 | default: |
10259 | 69 | break; |
10260 | 1.05k | } |
10261 | 1.01k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
10262 | 1.01k | } |
10263 | 152 | break; |
10264 | 152 | case 10: /* buffer ready */ |
10265 | 464 | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
10266 | 461 | lastoffset = offset; |
10267 | 461 | switch (fTagNo(tvb, offset)) { |
10268 | 185 | case 0: /* buffer-property */ |
10269 | 185 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10270 | 185 | offset = fDeviceObjectPropertyReference(tvb, pinfo, subtree, offset); |
10271 | 185 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10272 | 185 | break; |
10273 | 167 | case 1: |
10274 | 167 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, |
10275 | 167 | "previous-notification: "); |
10276 | 167 | break; |
10277 | 12 | case 2: |
10278 | 12 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, |
10279 | 12 | "current-notification: "); |
10280 | 12 | lastoffset = offset; |
10281 | 12 | break; |
10282 | 97 | default: |
10283 | 97 | break; |
10284 | 461 | } |
10285 | 452 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
10286 | 452 | } |
10287 | 112 | break; |
10288 | 112 | case 11: /* unsigned range */ |
10289 | 922 | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
10290 | 919 | lastoffset = offset; |
10291 | 919 | switch (fTagNo(tvb, offset)) { |
10292 | 672 | case 0: |
10293 | 672 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, |
10294 | 672 | "exceeding-value: "); |
10295 | 672 | break; |
10296 | 150 | case 1: |
10297 | 150 | offset = fBitStringTagVS(tvb, pinfo, subtree, offset, |
10298 | 150 | "status-flags: ", BACnetStatusFlags); |
10299 | 150 | break; |
10300 | 15 | case 2: |
10301 | 15 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, |
10302 | 15 | "exceeded-limit: "); |
10303 | 15 | lastoffset = offset; |
10304 | 15 | break; |
10305 | 82 | default: |
10306 | 82 | break; |
10307 | 919 | } |
10308 | 913 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
10309 | 913 | } |
10310 | 98 | break; |
10311 | | /* 12 reserved */ |
10312 | 218 | case 13: /* access-event */ |
10313 | 3.86k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
10314 | 3.85k | lastoffset = offset; |
10315 | 3.85k | switch (fTagNo(tvb, offset)) { |
10316 | 2.10k | case 0: |
10317 | 2.10k | offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset, |
10318 | 2.10k | "access event: ", BACnetAccessEvent, 512); |
10319 | 2.10k | break; |
10320 | 403 | case 1: |
10321 | 403 | offset = fBitStringTagVS(tvb, pinfo, subtree, offset, |
10322 | 403 | "status-flags: ", BACnetStatusFlags); |
10323 | 403 | break; |
10324 | 343 | case 2: |
10325 | 343 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, |
10326 | 343 | "access-event-tag: "); |
10327 | 343 | break; |
10328 | 360 | case 3: |
10329 | 360 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10330 | 360 | offset = fTimeStamp(tvb, pinfo, subtree, offset, "access-event-time: "); |
10331 | 360 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10332 | 360 | break; |
10333 | 455 | case 4: |
10334 | 455 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10335 | 455 | offset = fDeviceObjectReference(tvb, pinfo, subtree, offset); |
10336 | 455 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10337 | 455 | break; |
10338 | 58 | case 5: /* optional authentication-factor */ |
10339 | 58 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10340 | 58 | offset = fAuthenticationFactor(tvb, pinfo, subtree, offset); |
10341 | 58 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10342 | 58 | lastoffset = offset; |
10343 | 58 | break; |
10344 | 136 | default: |
10345 | 136 | break; |
10346 | 3.85k | } |
10347 | 3.83k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
10348 | 3.83k | } |
10349 | 199 | break; |
10350 | 199 | case 14: /* double-out-of-range */ |
10351 | 530 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
10352 | 526 | lastoffset = offset; |
10353 | 526 | switch (fTagNo(tvb, offset)) { |
10354 | 234 | case 0: |
10355 | 234 | offset = fDoubleTag(tvb, pinfo, subtree, offset, "exceeding-value: "); |
10356 | 234 | break; |
10357 | 111 | case 1: |
10358 | 111 | offset = fBitStringTagVS(tvb, pinfo, subtree, offset, |
10359 | 111 | "status-flags: ", BACnetStatusFlags); |
10360 | 111 | break; |
10361 | 105 | case 2: |
10362 | 105 | offset = fDoubleTag(tvb, pinfo, subtree, offset, "deadband: "); |
10363 | 105 | break; |
10364 | 15 | case 3: |
10365 | 15 | offset = fDoubleTag(tvb, pinfo, subtree, offset, "exceeded-limit: "); |
10366 | 15 | lastoffset = offset; |
10367 | 15 | break; |
10368 | 61 | default: |
10369 | 61 | break; |
10370 | 526 | } |
10371 | 515 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
10372 | 515 | } |
10373 | 78 | break; |
10374 | 81 | case 15: /* signed-out-of-range */ |
10375 | 1.11k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
10376 | 1.11k | lastoffset = offset; |
10377 | 1.11k | switch (fTagNo(tvb, offset)) { |
10378 | 937 | case 0: |
10379 | 937 | offset = fSignedTag(tvb, pinfo, subtree, offset, "exceeding-value: "); |
10380 | 937 | break; |
10381 | 60 | case 1: |
10382 | 60 | offset = fBitStringTagVS(tvb, pinfo, subtree, offset, |
10383 | 60 | "status-flags: ", BACnetStatusFlags); |
10384 | 60 | break; |
10385 | 43 | case 2: |
10386 | 43 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "deadband: "); |
10387 | 43 | break; |
10388 | 30 | case 3: |
10389 | 30 | offset = fSignedTag(tvb, pinfo, subtree, offset, "exceeded-limit: "); |
10390 | 30 | lastoffset = offset; |
10391 | 30 | break; |
10392 | 48 | default: |
10393 | 48 | break; |
10394 | 1.11k | } |
10395 | 1.11k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
10396 | 1.11k | } |
10397 | 79 | break; |
10398 | 79 | case 16: /* unsigned-out-of-range */ |
10399 | 1.55k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
10400 | 1.55k | lastoffset = offset; |
10401 | 1.55k | switch (fTagNo(tvb, offset)) { |
10402 | 903 | case 0: |
10403 | 903 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "exceeding-value: "); |
10404 | 903 | break; |
10405 | 266 | case 1: |
10406 | 266 | offset = fBitStringTagVS(tvb, pinfo, subtree, offset, |
10407 | 266 | "status-flags: ", BACnetStatusFlags); |
10408 | 266 | break; |
10409 | 335 | case 2: |
10410 | 335 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "deadband: "); |
10411 | 335 | break; |
10412 | 7 | case 3: |
10413 | 7 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "exceeded-limit: "); |
10414 | 7 | lastoffset = offset; |
10415 | 7 | break; |
10416 | 40 | default: |
10417 | 40 | break; |
10418 | 1.55k | } |
10419 | 1.54k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
10420 | 1.54k | } |
10421 | 52 | break; |
10422 | 52 | case 17: /* change-of-characterstring */ |
10423 | 51 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
10424 | 51 | lastoffset = offset; |
10425 | 51 | switch (fTagNo(tvb, offset)) { |
10426 | 30 | case 0: |
10427 | | /* changed-value (CharacterString) */ |
10428 | 30 | offset = fCharacterString(tvb, pinfo, subtree, offset, "changed-value: "); |
10429 | 30 | break; |
10430 | 9 | case 1: |
10431 | 9 | offset = fBitStringTagVS(tvb, pinfo, subtree, offset, |
10432 | 9 | "status-flags: ", BACnetStatusFlags); |
10433 | 9 | break; |
10434 | 1 | case 2: |
10435 | | /* alarm-value (CharacterString) */ |
10436 | 1 | offset = fCharacterString(tvb, pinfo, subtree, offset, "alarm-value: "); |
10437 | 1 | lastoffset = offset; |
10438 | 1 | break; |
10439 | 11 | default: |
10440 | 11 | break; |
10441 | 51 | } |
10442 | 49 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
10443 | 49 | } |
10444 | 12 | break; |
10445 | 32 | case 18: /* change-of-status-flags */ |
10446 | 288 | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
10447 | | /* exit loop if nothing happens inside */ |
10448 | 286 | lastoffset = offset; |
10449 | 286 | switch (fTagNo(tvb, offset)) { |
10450 | 262 | case 0: |
10451 | 262 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10452 | | |
10453 | 262 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
10454 | 262 | if (tag_is_context_specific(tag_info)) { |
10455 | 31 | propertyIdentifier = 85; /* suppose present-value here */ |
10456 | 31 | offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset); |
10457 | 231 | } else { |
10458 | 231 | offset = fPresentValue(tvb, pinfo, tree, offset, BACnetStatusFlags, 0, BACAPP_PRESENT_VALUE_ENUM); |
10459 | 231 | } |
10460 | | |
10461 | 262 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10462 | 262 | break; |
10463 | 2 | case 1: |
10464 | 2 | offset = fBitStringTagVS(tvb, pinfo, subtree, offset, |
10465 | 2 | "referenced-flags: ", BACnetStatusFlags); |
10466 | 2 | lastoffset = offset; |
10467 | 2 | break; |
10468 | 22 | default: |
10469 | 22 | break; |
10470 | 286 | } |
10471 | 279 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
10472 | 279 | } |
10473 | 25 | break; |
10474 | 36 | case 19: /* change-of-reliability */ |
10475 | 668 | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
10476 | | /* exit loop if nothing happens inside */ |
10477 | 667 | lastoffset = offset; |
10478 | | |
10479 | 667 | switch (fTagNo(tvb, offset)) { |
10480 | 375 | case 0: |
10481 | 375 | offset = fEnumeratedTag(tvb, pinfo, subtree, offset, "reliability:", BACnetReliability); |
10482 | 375 | break; |
10483 | 111 | case 1: |
10484 | 111 | offset = fBitStringTagVS(tvb, pinfo, subtree, offset, "status-flags: ", BACnetStatusFlags); |
10485 | 111 | break; |
10486 | 152 | case 2: /* property-values */ |
10487 | 152 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
10488 | 152 | if (tag_is_closing(tag_info)) { |
10489 | 2 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10490 | 2 | return offset; |
10491 | 2 | } |
10492 | 150 | pvtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "property-values"); |
10493 | 150 | offset += fTagHeaderTree(tvb, pinfo, pvtree, offset, &tag_no, &tag_info, &lvt); |
10494 | 150 | offset = fBACnetPropertyValue(tvb, pinfo, pvtree, offset); |
10495 | 150 | offset += fTagHeaderTree(tvb, pinfo, pvtree, offset, &tag_no, &tag_info, &lvt); |
10496 | 150 | break; |
10497 | 29 | default: |
10498 | 29 | break; |
10499 | 667 | } |
10500 | 661 | if (offset <= lastoffset) |
10501 | 29 | break; /* nothing happened, exit loop */ |
10502 | 661 | } |
10503 | 30 | break; |
10504 | 30 | case 20: /* context tag [20] is not used */ |
10505 | 7 | break; |
10506 | 25 | case 21: /* change-of-discrete-value */ |
10507 | 297 | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
10508 | | /* exit loop if nothing happens inside */ |
10509 | 296 | lastoffset = offset; |
10510 | 296 | switch (fTagNo(tvb, offset)) { |
10511 | 238 | case 0: /* new-value */ |
10512 | 238 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10513 | | |
10514 | 238 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
10515 | 238 | if (tag_is_opening(tag_info)) |
10516 | 19 | { |
10517 | 19 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10518 | 19 | offset = fDateTime(tvb, pinfo, subtree, offset, "new-value: "); |
10519 | 19 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10520 | 19 | } |
10521 | 219 | else |
10522 | 219 | { |
10523 | 219 | offset = fApplicationTypes(tvb, pinfo, subtree, offset, "new-value: "); |
10524 | 219 | } |
10525 | | |
10526 | 238 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10527 | 238 | break; |
10528 | 35 | case 1: /* status-flags */ |
10529 | 35 | offset = fBitStringTagVS(tvb, pinfo, subtree, offset, |
10530 | 35 | "status-flags: ", BACnetStatusFlags); |
10531 | 35 | break; |
10532 | 23 | default: |
10533 | 23 | break; |
10534 | 296 | } |
10535 | 295 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
10536 | 295 | } |
10537 | 24 | break; |
10538 | 65 | case 22: /* change-of-timer */ |
10539 | 2.54k | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
10540 | | /* exit loop if nothing happens inside */ |
10541 | 2.54k | lastoffset = offset; |
10542 | 2.54k | switch (fTagNo(tvb, offset)) { |
10543 | 1.74k | case 0: /* new-state */ |
10544 | 1.74k | offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset, |
10545 | 1.74k | "new-state: ", BACnetTimerState, 256); |
10546 | 1.74k | break; |
10547 | 76 | case 1: /* status-flags */ |
10548 | 76 | offset = fBitStringTagVS(tvb, pinfo, subtree, offset, |
10549 | 76 | "status-flags: ", BACnetStatusFlags); |
10550 | 76 | break; |
10551 | 204 | case 2: /* update-time */ |
10552 | 204 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10553 | 204 | offset = fDateTime(tvb, pinfo, subtree, offset, "update-time: "); |
10554 | 204 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10555 | 204 | break; |
10556 | 330 | case 3: /* last-state-change (OPTIONAL) */ |
10557 | 330 | offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset, |
10558 | 330 | "new-state: ", BACnetTimerTransition, 256); |
10559 | 330 | break; |
10560 | 131 | case 4: /* initial-timeout (OPTIONAL) */ |
10561 | 131 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "initial-timeout: "); |
10562 | 131 | break; |
10563 | 57 | default: |
10564 | 57 | break; |
10565 | 2.54k | } |
10566 | 2.53k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
10567 | 2.53k | } |
10568 | 59 | break; |
10569 | | |
10570 | | /* todo: add new parameters here ... */ |
10571 | 1.48k | default: |
10572 | 1.48k | offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset); |
10573 | 1.48k | break; |
10574 | 5.67k | } |
10575 | | |
10576 | | /* Closing tag for parameter choice */ |
10577 | 4.84k | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10578 | | |
10579 | 4.84k | return offset; |
10580 | 5.67k | } |
10581 | | |
10582 | | static unsigned |
10583 | | // NOLINTNEXTLINE(misc-no-recursion) |
10584 | | fEventParameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
10585 | 29.1k | { |
10586 | 29.1k | unsigned lastoffset = offset; |
10587 | 29.1k | uint8_t tag_no, tag_info; |
10588 | 29.1k | uint32_t lvt; |
10589 | 29.1k | proto_tree *subtree = tree; |
10590 | | |
10591 | 29.1k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
10592 | 29.1k | subtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0, |
10593 | 29.1k | ett_bacapp_value, NULL, "event parameters (%d) %s", |
10594 | 29.1k | tag_no, val_to_str_const(tag_no, BACnetEventType, "invalid type")); |
10595 | | |
10596 | | /* Opening tag for parameter choice */ |
10597 | 29.1k | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10598 | | |
10599 | 29.1k | switch (tag_no) { |
10600 | 3.22k | case 0: /* change-of-bitstring */ |
10601 | 14.5k | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */ |
10602 | 11.7k | lastoffset = offset; |
10603 | 11.7k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
10604 | 11.7k | if (tag_is_closing(tag_info)) { |
10605 | 345 | break; |
10606 | 345 | } |
10607 | 11.4k | switch (tag_no) { |
10608 | 7.88k | case 0: |
10609 | 7.88k | offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay"); |
10610 | 7.88k | break; |
10611 | 665 | case 1: |
10612 | 665 | offset = fBitStringTag(tvb, pinfo, subtree, offset, "bitmask: "); |
10613 | 665 | break; |
10614 | 181 | case 2: /* SEQUENCE OF BIT STRING */ |
10615 | 181 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10616 | 1.07k | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */ |
10617 | 972 | lastoffset = offset; |
10618 | 972 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
10619 | 972 | if (tag_is_closing(tag_info)) { |
10620 | 77 | break; |
10621 | 77 | } |
10622 | 895 | offset = fBitStringTag(tvb, pinfo, subtree, offset, |
10623 | 895 | "bitstring value: "); |
10624 | 895 | } |
10625 | 181 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10626 | 181 | break; |
10627 | 2.70k | default: |
10628 | 2.70k | break; |
10629 | 11.4k | } |
10630 | 11.4k | } |
10631 | 3.09k | break; |
10632 | 3.09k | case 1: /* change-of-state */ |
10633 | 2.99k | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */ |
10634 | 2.17k | lastoffset = offset; |
10635 | 2.17k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
10636 | 2.17k | if (tag_is_closing(tag_info)) { |
10637 | 98 | break; |
10638 | 98 | } |
10639 | 2.07k | switch (tag_no) { |
10640 | 998 | case 0: |
10641 | 998 | offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay"); |
10642 | 998 | break; |
10643 | 274 | case 1: /* SEQUENCE OF BACnetPropertyStates */ |
10644 | 274 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10645 | 8.05k | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */ |
10646 | 7.97k | lastoffset = offset; |
10647 | 7.97k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
10648 | 7.97k | if (tag_is_closing(tag_info)) { |
10649 | 194 | break; |
10650 | 194 | } |
10651 | 7.78k | offset = fBACnetPropertyStates(tvb, pinfo, subtree, offset); |
10652 | 7.78k | } |
10653 | 274 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10654 | 274 | break; |
10655 | 805 | default: |
10656 | 805 | break; |
10657 | 2.07k | } |
10658 | 2.07k | } |
10659 | 920 | break; |
10660 | 2.32k | case 2: /* change-of-value */ |
10661 | 6.79k | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */ |
10662 | 4.48k | lastoffset = offset; |
10663 | 4.48k | switch (fTagNo(tvb, offset)) { |
10664 | 1.84k | case 0: |
10665 | 1.84k | offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay"); |
10666 | 1.84k | break; |
10667 | 342 | case 1: /* don't loop it, it's a CHOICE */ |
10668 | 342 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10669 | 342 | switch (fTagNo(tvb, offset)) { |
10670 | 25 | case 0: |
10671 | 25 | offset = fBitStringTag(tvb, pinfo, subtree, offset, "bitmask: "); |
10672 | 25 | break; |
10673 | 228 | case 1: |
10674 | 228 | offset = fRealTag(tvb, pinfo, subtree, offset, |
10675 | 228 | "referenced Property Increment: "); |
10676 | 228 | break; |
10677 | 88 | default: |
10678 | 88 | break; |
10679 | 342 | } |
10680 | 337 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10681 | 337 | break; |
10682 | 2.29k | default: |
10683 | 2.29k | break; |
10684 | 4.48k | } |
10685 | 4.48k | } |
10686 | 2.31k | break; |
10687 | 2.31k | case 3: /* command-failure */ |
10688 | 4.46k | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */ |
10689 | 2.92k | lastoffset = offset; |
10690 | 2.92k | tag_no = fTagNo(tvb, offset); |
10691 | 2.92k | switch (tag_no) { |
10692 | 992 | case 0: |
10693 | 992 | offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay"); |
10694 | 992 | break; |
10695 | 398 | case 1: |
10696 | 398 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10697 | 398 | offset = fDeviceObjectPropertyReference(tvb, pinfo, subtree, offset); |
10698 | 398 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10699 | 398 | break; |
10700 | 1.53k | default: |
10701 | 1.53k | break; |
10702 | 2.92k | } |
10703 | 2.92k | } |
10704 | 1.54k | break; |
10705 | 1.54k | case 4: /* floating-limit */ |
10706 | 9.03k | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */ |
10707 | 7.83k | lastoffset = offset; |
10708 | 7.83k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
10709 | 7.83k | if (tag_is_closing(tag_info)) { |
10710 | 268 | break; |
10711 | 268 | } |
10712 | 7.56k | switch (tag_no) { |
10713 | 3.65k | case 0: |
10714 | 3.65k | offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay"); |
10715 | 3.65k | break; |
10716 | 610 | case 1: |
10717 | 610 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10718 | 610 | offset = fDeviceObjectPropertyReference(tvb, pinfo, subtree, offset); |
10719 | 610 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10720 | 610 | break; |
10721 | 340 | case 2: |
10722 | 340 | offset = fRealTag(tvb, pinfo, subtree, offset, "low diff limit: "); |
10723 | 340 | break; |
10724 | 453 | case 3: |
10725 | 453 | offset = fRealTag(tvb, pinfo, subtree, offset, "high diff limit: "); |
10726 | 453 | break; |
10727 | 1.33k | case 4: |
10728 | 1.33k | offset = fRealTag(tvb, pinfo, subtree, offset, "deadband: "); |
10729 | 1.33k | break; |
10730 | 1.17k | default: |
10731 | 1.17k | break; |
10732 | 7.56k | } |
10733 | 7.56k | } |
10734 | 1.47k | break; |
10735 | 1.55k | case 5: /* out-of-range */ |
10736 | 5.40k | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */ |
10737 | 3.85k | lastoffset = offset; |
10738 | 3.85k | switch (fTagNo(tvb, offset)) { |
10739 | 1.35k | case 0: |
10740 | 1.35k | offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay"); |
10741 | 1.35k | break; |
10742 | 293 | case 1: |
10743 | 293 | offset = fRealTag(tvb, pinfo, subtree, offset, "low limit: "); |
10744 | 293 | break; |
10745 | 381 | case 2: |
10746 | 381 | offset = fRealTag(tvb, pinfo, subtree, offset, "high limit: "); |
10747 | 381 | break; |
10748 | 298 | case 3: |
10749 | 298 | offset = fRealTag(tvb, pinfo, subtree, offset, "deadband: "); |
10750 | 298 | break; |
10751 | 1.53k | default: |
10752 | 1.53k | break; |
10753 | 3.85k | } |
10754 | 3.85k | } |
10755 | 1.54k | break; |
10756 | 1.91k | case 6: /* complex-event-type */ |
10757 | | /* deprecated */ |
10758 | 1.91k | offset = fBACnetPropertyValue (tvb, pinfo, tree, offset); |
10759 | 1.91k | break; |
10760 | 2.65k | case 7: /* buffer-ready */ |
10761 | | /* deprecated */ |
10762 | 5.06k | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { |
10763 | 5.04k | lastoffset = offset; |
10764 | 5.04k | switch (fTagNo(tvb, offset)) { |
10765 | 1.65k | case 0: |
10766 | 1.65k | offset = fUnsignedTag(tvb, pinfo, tree, offset, "notification threshold"); |
10767 | 1.65k | break; |
10768 | 751 | case 1: |
10769 | 751 | offset = fUnsignedTag(tvb, pinfo, tree, offset, |
10770 | 751 | "previous notification count: "); |
10771 | 751 | break; |
10772 | 2.63k | default: |
10773 | 2.63k | return offset; |
10774 | 5.04k | } |
10775 | 5.04k | } |
10776 | 18 | break; |
10777 | 1.74k | case 8: /* change-of-life-safety */ |
10778 | 5.09k | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */ |
10779 | 3.39k | lastoffset = offset; |
10780 | 3.39k | switch (fTagNo(tvb, offset)) { |
10781 | 1.18k | case 0: |
10782 | 1.18k | offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay"); |
10783 | 1.18k | break; |
10784 | 166 | case 1: |
10785 | 166 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10786 | 1.29k | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */ |
10787 | 1.28k | lastoffset = offset; |
10788 | 1.28k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
10789 | 1.28k | if (tag_is_closing(tag_info)) { |
10790 | 151 | break; |
10791 | 151 | } |
10792 | 1.13k | offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset, |
10793 | 1.13k | "life safety alarm value: ", BACnetLifeSafetyState, 256); |
10794 | 1.13k | } |
10795 | 166 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10796 | 166 | break; |
10797 | 196 | case 2: |
10798 | 196 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10799 | 1.62k | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */ |
10800 | 1.60k | lastoffset = offset; |
10801 | 1.60k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
10802 | 1.60k | if (tag_is_closing(tag_info)) { |
10803 | 173 | break; |
10804 | 173 | } |
10805 | 1.42k | offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset, |
10806 | 1.42k | "alarm value: ", BACnetLifeSafetyState, 256); |
10807 | 1.42k | } |
10808 | 196 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10809 | 196 | break; |
10810 | 154 | case 3: |
10811 | 154 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10812 | 154 | offset = fDeviceObjectPropertyReference(tvb, pinfo, subtree, offset); |
10813 | 154 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10814 | 154 | break; |
10815 | 1.69k | default: |
10816 | 1.69k | break; |
10817 | 3.39k | } |
10818 | 3.39k | } |
10819 | 1.70k | break; |
10820 | 2.66k | case 9: /* extended */ |
10821 | 4.49k | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */ |
10822 | 4.49k | lastoffset = offset; |
10823 | 4.49k | switch (fTagNo(tvb, offset)) { |
10824 | 1.41k | case 0: |
10825 | 1.41k | offset = fVendorIdentifier(tvb, pinfo, tree, offset); |
10826 | 1.41k | break; |
10827 | 431 | case 1: |
10828 | 431 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "extended-event-type: "); |
10829 | 431 | break; |
10830 | 308 | case 2: /* parameters */ |
10831 | 308 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
10832 | 4.46k | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */ |
10833 | 4.19k | lastoffset = offset; |
10834 | 4.19k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
10835 | 4.19k | if (tag_is_closing(tag_info) && tag_no == 2) { |
10836 | 31 | break; |
10837 | 31 | } |
10838 | | |
10839 | 4.16k | if ( ! tag_is_context_specific(tag_info)) { |
10840 | 3.10k | offset = fApplicationTypes(tvb, pinfo, tree, offset, "parameters: "); |
10841 | 3.10k | } else { |
10842 | 1.05k | if (tag_no == 0) { |
10843 | 550 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
10844 | 550 | offset = fDeviceObjectPropertyReference(tvb, pinfo, tree, offset); |
10845 | 550 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
10846 | 550 | } else { |
10847 | 503 | offset = fAbstractSyntaxNType(tvb, pinfo, tree, offset); |
10848 | 503 | } |
10849 | 1.05k | } |
10850 | 4.16k | } |
10851 | 308 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
10852 | 308 | lastoffset = offset; |
10853 | 308 | break; |
10854 | 2.33k | default: |
10855 | 2.33k | break; |
10856 | 4.49k | } |
10857 | 4.33k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
10858 | 4.33k | } |
10859 | 2.50k | break; |
10860 | 2.50k | case 10: /* buffer-ready */ |
10861 | 3.67k | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */ |
10862 | 2.49k | lastoffset = offset; |
10863 | 2.49k | switch (fTagNo(tvb, offset)) { |
10864 | 843 | case 0: |
10865 | 843 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, |
10866 | 843 | "notification-threshold: "); |
10867 | 843 | break; |
10868 | 474 | case 1: |
10869 | 474 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, |
10870 | 474 | "previous-notification-count: "); |
10871 | 474 | break; |
10872 | 1.17k | default: |
10873 | 1.17k | break; |
10874 | 2.49k | } |
10875 | 2.49k | } |
10876 | 1.18k | break; |
10877 | 1.45k | case 11: /* unsigned-range */ |
10878 | 4.42k | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */ |
10879 | 2.97k | lastoffset = offset; |
10880 | 2.97k | switch (fTagNo(tvb, offset)) { |
10881 | 1.12k | case 0: |
10882 | 1.12k | offset = fTimeSpan(tvb, pinfo, tree, offset, "Time Delay"); |
10883 | 1.12k | break; |
10884 | 234 | case 1: |
10885 | 234 | offset = fUnsignedTag(tvb, pinfo, tree, offset, |
10886 | 234 | "low-limit: "); |
10887 | 234 | break; |
10888 | 172 | case 2: |
10889 | 172 | offset = fUnsignedTag(tvb, pinfo, tree, offset, |
10890 | 172 | "high-limit: "); |
10891 | 172 | break; |
10892 | 1.44k | default: |
10893 | 1.44k | break; |
10894 | 2.97k | } |
10895 | 2.97k | } |
10896 | 1.45k | break; |
10897 | 1.45k | case 13: /* access-event */ |
10898 | 3.23k | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */ |
10899 | 1.94k | lastoffset = offset; |
10900 | 1.94k | switch (fTagNo(tvb, offset)) { |
10901 | 461 | case 0: |
10902 | | /* TODO: [0] SEQUENCE OF BACnetAccessEvent */ |
10903 | 461 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10904 | 2.71k | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */ |
10905 | 2.67k | lastoffset = offset; |
10906 | 2.67k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
10907 | 2.67k | if (tag_is_closing(tag_info)) { |
10908 | 426 | break; |
10909 | 426 | } |
10910 | 2.25k | offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset, |
10911 | 2.25k | "access event: ", BACnetAccessEvent, 512); |
10912 | 2.25k | } |
10913 | 461 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10914 | 461 | break; |
10915 | 202 | case 1: |
10916 | 202 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10917 | 202 | offset = fDeviceObjectPropertyReference(tvb, pinfo, subtree, offset); |
10918 | 202 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10919 | 202 | break; |
10920 | 1.28k | default: |
10921 | 1.28k | break; |
10922 | 1.94k | } |
10923 | 1.94k | } |
10924 | 1.28k | break; |
10925 | 1.54k | case 14: /* double-out-of-range */ |
10926 | 5.86k | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */ |
10927 | 4.34k | lastoffset = offset; |
10928 | 4.34k | switch (fTagNo(tvb, offset)) { |
10929 | 1.93k | case 0: |
10930 | 1.93k | offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay"); |
10931 | 1.93k | break; |
10932 | 230 | case 1: |
10933 | 230 | offset = fDoubleTag(tvb, pinfo, subtree, offset, "low limit: "); |
10934 | 230 | break; |
10935 | 391 | case 2: |
10936 | 391 | offset = fDoubleTag(tvb, pinfo, subtree, offset, "high limit: "); |
10937 | 391 | break; |
10938 | 287 | case 3: |
10939 | 287 | offset = fDoubleTag(tvb, pinfo, subtree, offset, "deadband: "); |
10940 | 287 | break; |
10941 | 1.51k | default: |
10942 | 1.51k | break; |
10943 | 4.34k | } |
10944 | 4.34k | } |
10945 | 1.52k | break; |
10946 | 1.52k | case 15: /* signed-out-of-range */ |
10947 | 1.12k | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */ |
10948 | 1.03k | lastoffset = offset; |
10949 | 1.03k | switch (fTagNo(tvb, offset)) { |
10950 | 481 | case 0: |
10951 | 481 | offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay"); |
10952 | 481 | break; |
10953 | 87 | case 1: |
10954 | 87 | offset = fSignedTag(tvb, pinfo, subtree, offset, "low limit: "); |
10955 | 87 | break; |
10956 | 188 | case 2: |
10957 | 188 | offset = fSignedTag(tvb, pinfo, subtree, offset, "high limit: "); |
10958 | 188 | break; |
10959 | 197 | case 3: |
10960 | 197 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "deadband: "); |
10961 | 197 | break; |
10962 | 82 | default: |
10963 | 82 | break; |
10964 | 1.03k | } |
10965 | 1.03k | } |
10966 | 87 | break; |
10967 | 94 | case 16: /* unsigned-out-of-range */ |
10968 | 2.56k | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */ |
10969 | 2.47k | lastoffset = offset; |
10970 | 2.47k | switch (fTagNo(tvb, offset)) { |
10971 | 1.03k | case 0: |
10972 | 1.03k | offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay"); |
10973 | 1.03k | break; |
10974 | 1.12k | case 1: |
10975 | 1.12k | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "low limit: "); |
10976 | 1.12k | break; |
10977 | 57 | case 2: |
10978 | 57 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "high limit: "); |
10979 | 57 | break; |
10980 | 173 | case 3: |
10981 | 173 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "deadband: "); |
10982 | 173 | break; |
10983 | 83 | default: |
10984 | 83 | break; |
10985 | 2.47k | } |
10986 | 2.47k | } |
10987 | 94 | break; |
10988 | 94 | case 17: /* change-of-characterstring */ |
10989 | 214 | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */ |
10990 | 193 | lastoffset = offset; |
10991 | 193 | switch (fTagNo(tvb, offset)) { |
10992 | 143 | case 0: |
10993 | 143 | offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay"); |
10994 | 143 | break; |
10995 | 29 | case 1: /* SEQUENCE OF CharacterString */ |
10996 | 29 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
10997 | 304 | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */ |
10998 | 292 | lastoffset = offset; |
10999 | 292 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11000 | 292 | if (tag_is_closing(tag_info)) { |
11001 | 17 | break; |
11002 | 17 | } |
11003 | 275 | offset = fCharacterString(tvb, pinfo, tree, offset, "alarm value: "); |
11004 | 275 | } |
11005 | 29 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11006 | 29 | break; |
11007 | 21 | default: |
11008 | 21 | break; |
11009 | 193 | } |
11010 | 193 | } |
11011 | 21 | break; |
11012 | 39 | case 18: /* change-of-status-flags */ |
11013 | 509 | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */ |
11014 | 473 | lastoffset = offset; |
11015 | 473 | switch (fTagNo(tvb, offset)) { |
11016 | 344 | case 0: |
11017 | 344 | offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay"); |
11018 | 344 | break; |
11019 | 94 | case 1: |
11020 | 94 | offset = fBitStringTagVS(tvb, pinfo, subtree, offset, |
11021 | 94 | "selected flags: ", BACnetStatusFlags); |
11022 | 94 | break; |
11023 | 35 | default: |
11024 | 35 | break; |
11025 | 473 | } |
11026 | 473 | } |
11027 | 36 | break; |
11028 | 36 | case 19: /* has been intentionally omitted. It parallels the change-of-reliability event type */ |
11029 | 0 | break; |
11030 | 14 | case 20: /* none */ |
11031 | | /* no closing tag expected only context tag here */ |
11032 | 14 | return offset; |
11033 | 15 | case 21: /* change-of-discrete-value */ |
11034 | 170 | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */ |
11035 | 155 | lastoffset = offset; |
11036 | 155 | switch (fTagNo(tvb, offset)) { |
11037 | 140 | case 0: |
11038 | 140 | offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay"); |
11039 | 140 | break; |
11040 | 15 | default: |
11041 | 15 | break; |
11042 | 155 | } |
11043 | 155 | } |
11044 | 15 | break; |
11045 | 80 | case 22: /* change-of-timer */ |
11046 | 532 | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */ |
11047 | 459 | lastoffset = offset; |
11048 | 459 | switch (fTagNo(tvb, offset)) { |
11049 | 200 | case 0: /* time-delay */ |
11050 | 200 | offset = fTimeSpan(tvb, pinfo, subtree, offset, "Time Delay"); |
11051 | 200 | break; |
11052 | 85 | case 1: /* alarm-values */ |
11053 | 85 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11054 | 750 | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */ |
11055 | 743 | lastoffset = offset; |
11056 | 743 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11057 | 743 | if (tag_is_closing(tag_info)) { |
11058 | 78 | break; |
11059 | 78 | } |
11060 | 665 | offset = fEnumeratedTag(tvb, pinfo, subtree, offset, |
11061 | 665 | "alarm value: ", BACnetTimerState); |
11062 | 665 | } |
11063 | 85 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11064 | 85 | break; |
11065 | 108 | case 2: /* update-time-reference */ |
11066 | 108 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11067 | 108 | offset = fDeviceObjectPropertyReference(tvb, pinfo, subtree, offset); |
11068 | 108 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11069 | 108 | break; |
11070 | 66 | default: |
11071 | 66 | break; |
11072 | 459 | } |
11073 | 459 | } |
11074 | 73 | break; |
11075 | | /* todo: add new event-parameter cases here */ |
11076 | 3.08k | default: |
11077 | 3.08k | break; |
11078 | 29.1k | } |
11079 | | |
11080 | | /* Closing tag for parameter choice */ |
11081 | 25.8k | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11082 | 25.8k | return offset; |
11083 | 29.1k | } |
11084 | | |
11085 | | static unsigned |
11086 | | fFaultParameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
11087 | 8.43k | { |
11088 | 8.43k | unsigned lastoffset = offset; |
11089 | 8.43k | uint8_t tag_no, tag_info; |
11090 | 8.43k | uint32_t lvt; |
11091 | 8.43k | proto_tree *subtree = tree; |
11092 | | |
11093 | 8.43k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11094 | 8.43k | subtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0, |
11095 | 8.43k | ett_bacapp_value, NULL, "fault parameters (%d) %s", |
11096 | 8.43k | tag_no, val_to_str_const(tag_no, BACnetFaultType, "invalid type")); |
11097 | | |
11098 | | /* Opening tag for parameter choice */ |
11099 | 8.43k | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11100 | | |
11101 | 8.43k | switch (tag_no) { |
11102 | 2.85k | case 0: /* none */ |
11103 | | /* no closing tag expected only context tag here */ |
11104 | 2.85k | return offset; |
11105 | 529 | case 1: /* fault-characterstring */ |
11106 | 1.04k | while ((tvb_reported_length_remaining(tvb, offset) > 0) && (offset>lastoffset)) { /* exit loop if nothing happens inside */ |
11107 | 539 | lastoffset = offset; |
11108 | 539 | switch (fTagNo(tvb, offset)) { |
11109 | 36 | case 0: /* SEQUENCE OF CharacterString */ |
11110 | 36 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11111 | 338 | while ((tvb_reported_length_remaining(tvb, offset) > 0) && (offset>lastoffset)) { /* exit loop if nothing happens inside */ |
11112 | 315 | lastoffset = offset; |
11113 | 315 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11114 | 315 | if (tag_is_closing(tag_info)) { |
11115 | 13 | break; |
11116 | 13 | } |
11117 | 302 | offset = fCharacterString(tvb, pinfo, subtree, offset, "fault value: "); |
11118 | 302 | } |
11119 | 36 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11120 | 36 | break; |
11121 | 503 | default: |
11122 | 503 | break; |
11123 | 539 | } |
11124 | 539 | } |
11125 | 506 | break; |
11126 | 514 | case 2: /* fault-extended */ |
11127 | 2.07k | while ((tvb_reported_length_remaining(tvb, offset) > 0) && (offset>lastoffset)) { /* exit loop if nothing happens inside */ |
11128 | 1.57k | lastoffset = offset; |
11129 | 1.57k | switch (fTagNo(tvb, offset)) { |
11130 | 845 | case 0: |
11131 | 845 | offset = fVendorIdentifier(tvb, pinfo, subtree, offset); |
11132 | 845 | break; |
11133 | 220 | case 1: |
11134 | 220 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "extended-fault-type: "); |
11135 | 220 | break; |
11136 | 148 | case 2: /* parameters */ |
11137 | 148 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11138 | 148 | offset = fApplicationTypes(tvb, pinfo, subtree, offset, "parameters: "); |
11139 | 148 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11140 | 148 | lastoffset = offset; |
11141 | 148 | break; |
11142 | 359 | default: |
11143 | 359 | break; |
11144 | 1.57k | } |
11145 | 1.57k | } |
11146 | 506 | break; |
11147 | 506 | case 3: /* fault-life-safety */ |
11148 | 725 | while ((tvb_reported_length_remaining(tvb, offset) > 0) && (offset>lastoffset)) { /* exit loop if nothing happens inside */ |
11149 | 442 | lastoffset = offset; |
11150 | 442 | switch (fTagNo(tvb, offset)) { |
11151 | 68 | case 0: |
11152 | 68 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11153 | 1.04k | while ((tvb_reported_length_remaining(tvb, offset) > 0) && (offset>lastoffset)) { /* exit loop if nothing happens inside */ |
11154 | 1.02k | lastoffset = offset; |
11155 | 1.02k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11156 | 1.02k | if (tag_is_closing(tag_info)) { |
11157 | 51 | break; |
11158 | 51 | } |
11159 | 974 | offset = fEnumeratedTag(tvb, pinfo, subtree, offset, |
11160 | 974 | "fault value: ", BACnetLifeSafetyState); |
11161 | 974 | } |
11162 | 68 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11163 | 68 | break; |
11164 | 94 | case 1: |
11165 | 94 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11166 | 94 | offset = fDeviceObjectPropertyReference(tvb, pinfo, subtree, offset); |
11167 | 94 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11168 | 94 | break; |
11169 | 280 | default: |
11170 | 280 | break; |
11171 | 442 | } |
11172 | 442 | } |
11173 | 283 | break; |
11174 | 526 | case 4: /* fault-state */ |
11175 | 1.07k | while ((tvb_reported_length_remaining(tvb, offset) > 0) && (offset>lastoffset)) { /* exit loop if nothing happens inside */ |
11176 | 581 | lastoffset = offset; |
11177 | 581 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11178 | 581 | if (tag_is_closing(tag_info)) { |
11179 | 17 | break; |
11180 | 17 | } |
11181 | 564 | switch (tag_no) { |
11182 | 73 | case 0: /* SEQUENCE OF BACnetPropertyStates */ |
11183 | 73 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11184 | 1.56k | while ((tvb_reported_length_remaining(tvb, offset) > 0) && (offset>lastoffset)) { /* exit loop if nothing happens inside */ |
11185 | 1.54k | lastoffset = offset; |
11186 | 1.54k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11187 | 1.54k | if (tag_is_closing(tag_info)) { |
11188 | 60 | break; |
11189 | 60 | } |
11190 | 1.48k | offset = fBACnetPropertyStates(tvb, pinfo, subtree, offset); |
11191 | 1.48k | } |
11192 | 73 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11193 | 73 | break; |
11194 | 491 | default: |
11195 | 491 | break; |
11196 | 564 | } |
11197 | 564 | } |
11198 | 513 | break; |
11199 | 513 | case 5: /* fault-status-flags */ |
11200 | 906 | while ((tvb_reported_length_remaining(tvb, offset) > 0) && (offset>lastoffset)) { /* exit loop if nothing happens inside */ |
11201 | 500 | lastoffset = offset; |
11202 | 500 | switch (fTagNo(tvb, offset)) { |
11203 | 98 | case 0: |
11204 | 98 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11205 | 98 | offset = fDeviceObjectPropertyReference(tvb, pinfo, subtree, offset); |
11206 | 98 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11207 | 98 | break; |
11208 | 402 | default: |
11209 | 402 | break; |
11210 | 500 | } |
11211 | 500 | } |
11212 | 406 | break; |
11213 | 1.21k | case 6: /* fault-out-of-range */ |
11214 | 2.88k | while ((tvb_reported_length_remaining(tvb, offset) > 0) && (offset>lastoffset)) { /* exit loop if nothing happens inside */ |
11215 | 1.74k | lastoffset = offset; |
11216 | 1.74k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11217 | 1.74k | if (tag_is_closing(tag_info)) { |
11218 | 69 | break; |
11219 | 69 | } |
11220 | 1.67k | switch (fTagNo(tvb, offset)) { |
11221 | 368 | case 0: |
11222 | 368 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11223 | 368 | offset = fApplicationTypes(tvb, pinfo, subtree, offset, "min-normal-value: "); |
11224 | 368 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11225 | 368 | break; |
11226 | 162 | case 1: |
11227 | 162 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11228 | 162 | offset = fApplicationTypes(tvb, pinfo, subtree, offset, "max-normal-value: "); |
11229 | 162 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11230 | 162 | break; |
11231 | 1.14k | default: |
11232 | 1.14k | break; |
11233 | 1.67k | } |
11234 | 1.67k | } |
11235 | 1.21k | break; |
11236 | 1.21k | case 7: /* fault-listed */ |
11237 | 954 | while ((tvb_reported_length_remaining(tvb, offset) > 0) && (offset>lastoffset)) { /* exit loop if nothing happens inside */ |
11238 | 511 | lastoffset = offset; |
11239 | 511 | switch (fTagNo(tvb, offset)) { |
11240 | 71 | case 0: |
11241 | 71 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11242 | 71 | offset = fDeviceObjectPropertyReference(tvb, pinfo, subtree, offset); |
11243 | 71 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11244 | 71 | break; |
11245 | 440 | default: |
11246 | 440 | break; |
11247 | 511 | } |
11248 | 511 | } |
11249 | 443 | break; |
11250 | 1.63k | default: |
11251 | 1.63k | break; |
11252 | 8.43k | } |
11253 | | |
11254 | | /* Closing tag for parameter choice */ |
11255 | 5.50k | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11256 | 5.50k | return offset; |
11257 | 8.43k | } |
11258 | | |
11259 | | static unsigned |
11260 | | fEventNotificationSubscription(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
11261 | 76 | { |
11262 | 76 | unsigned lastoffset = 0; |
11263 | 76 | uint8_t tag_no, tag_info; |
11264 | 76 | uint32_t lvt; |
11265 | 76 | proto_tree *subtree; |
11266 | 76 | unsigned itemno = 1; |
11267 | | |
11268 | 1.18k | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { /* exit loop if nothing happens inside */ |
11269 | 1.18k | lastoffset = offset; |
11270 | 1.18k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11271 | 1.18k | if (tag_is_closing(tag_info)) { |
11272 | 6 | return offset; |
11273 | 6 | } |
11274 | 1.17k | switch (tag_no) { |
11275 | 250 | case 0: /* recipient */ |
11276 | 250 | tree = proto_tree_add_subtree_format(tree, tvb, offset, 1, |
11277 | 250 | ett_bacapp_value, NULL, "Subscription %d", itemno); /* add tree label and indent */ |
11278 | 250 | itemno = itemno + 1; |
11279 | | |
11280 | 250 | subtree = proto_tree_add_subtree(tree, tvb, offset, 1, |
11281 | 250 | ett_bacapp_value, NULL, "Recipient: "); /* add tree label and indent */ |
11282 | 250 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* show context open */ |
11283 | 250 | offset = fRecipient(tvb, pinfo, subtree, offset); |
11284 | 250 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* show context close */ |
11285 | 250 | break; |
11286 | 179 | case 1: /* process-identifier */ |
11287 | 179 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "Process Identifier: "); |
11288 | 179 | break; |
11289 | 524 | case 2: /* issue-confirmed-notifications */ |
11290 | 524 | offset = fBooleanTag(tvb, pinfo, tree, offset, "Issue Confirmed Notifications: "); |
11291 | 524 | break; |
11292 | 156 | case 3: /* time-remaining */ |
11293 | 156 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "Time Remaining: "); |
11294 | 156 | break; |
11295 | 66 | default: |
11296 | 66 | return offset; |
11297 | 1.17k | } |
11298 | 1.17k | } |
11299 | | |
11300 | 3 | return offset; |
11301 | 76 | } |
11302 | | |
11303 | | static unsigned |
11304 | | fLightingCommand(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *lable) |
11305 | 219 | { |
11306 | 219 | unsigned lastoffset = 0; |
11307 | 219 | uint8_t tag_no, tag_info; |
11308 | 219 | uint32_t lvt; |
11309 | 219 | proto_tree *subtree = tree; |
11310 | | |
11311 | 219 | subtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0, |
11312 | 219 | ett_bacapp_value, NULL, "%s", lable); |
11313 | | |
11314 | 3.27k | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
11315 | 3.25k | lastoffset = offset; |
11316 | | /* check the tag. A closing tag means we are done */ |
11317 | 3.25k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11318 | 3.25k | if (tag_is_closing(tag_info)) { |
11319 | 61 | return offset; |
11320 | 61 | } |
11321 | 3.19k | switch (tag_no) { |
11322 | 1.35k | case 0: /* operation */ |
11323 | 1.35k | offset = fEnumeratedTag(tvb, pinfo, subtree, offset, "operation: ", BACnetLightingOperation); |
11324 | 1.35k | break; |
11325 | 300 | case 1: /* target-level */ |
11326 | 300 | offset = fRealTag(tvb, pinfo, subtree, offset, "target-level: "); |
11327 | 300 | break; |
11328 | 199 | case 2: /* ramp-rate */ |
11329 | 199 | offset = fRealTag(tvb, pinfo, subtree, offset, "ramp-rate: "); |
11330 | 199 | break; |
11331 | 198 | case 3: /* step-increment */ |
11332 | 198 | offset = fRealTag(tvb, pinfo, subtree, offset, "step-increment: "); |
11333 | 198 | break; |
11334 | 449 | case 4: /* fade-time */ |
11335 | 449 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "fade-time: "); |
11336 | 449 | break; |
11337 | 567 | case 5: /* priority */ |
11338 | 567 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "priority: "); |
11339 | 567 | break; |
11340 | 126 | default: |
11341 | 126 | return offset; |
11342 | 3.19k | } |
11343 | 3.19k | } |
11344 | | |
11345 | 23 | return offset; |
11346 | 219 | } |
11347 | | |
11348 | | static unsigned |
11349 | | fColorCommand(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, unsigned offset, const char* lable) |
11350 | 265 | { |
11351 | 265 | unsigned lastoffset = 0; |
11352 | 265 | uint8_t tag_no, tag_info; |
11353 | 265 | uint32_t lvt; |
11354 | 265 | proto_tree* subtree = tree; |
11355 | | |
11356 | 265 | subtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0, |
11357 | 265 | ett_bacapp_value, NULL, "%s", lable); |
11358 | | |
11359 | 3.07k | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
11360 | 3.05k | lastoffset = offset; |
11361 | | /* check the tag. A closing tag means we are done */ |
11362 | 3.05k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11363 | 3.05k | if (tag_is_closing(tag_info)) { |
11364 | 78 | return offset; |
11365 | 78 | } |
11366 | 2.98k | switch (tag_no) { |
11367 | 1.27k | case 0: /* operation */ |
11368 | 1.27k | offset = fEnumeratedTag(tvb, pinfo, subtree, offset, "operation: ", BACnetColorOperation); |
11369 | 1.27k | break; |
11370 | 203 | case 1: /* target-color */ |
11371 | 203 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11372 | 203 | offset = fXyColor(tvb, pinfo, subtree, offset, "xy-color: "); |
11373 | 203 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11374 | 203 | break; |
11375 | 355 | case 2: /* target-color-temperature */ |
11376 | 355 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "target-color-temperature: "); |
11377 | 355 | break; |
11378 | 268 | case 3: /* fade-time */ |
11379 | 268 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "fade-time: "); |
11380 | 268 | break; |
11381 | 404 | case 4: /* ramp-rate */ |
11382 | 404 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "ramp-rate: "); |
11383 | 404 | break; |
11384 | 313 | case 5: /* step-increment */ |
11385 | 313 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "step-increment: "); |
11386 | 313 | break; |
11387 | 165 | default: |
11388 | 165 | return offset; |
11389 | 2.98k | } |
11390 | 2.98k | } |
11391 | | |
11392 | 13 | return offset; |
11393 | 265 | } |
11394 | | |
11395 | | static unsigned |
11396 | | fXyColor(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, unsigned offset, const char* label) |
11397 | 413 | { |
11398 | 413 | proto_tree* subtree = tree; |
11399 | | |
11400 | 413 | if (label != NULL) { |
11401 | 413 | subtree = proto_tree_add_subtree(subtree, tvb, offset, 10, ett_bacapp_value, NULL, label); |
11402 | 413 | } |
11403 | 413 | offset = fRealTag(tvb, pinfo, subtree, offset, "x-coordinate: "); |
11404 | 413 | return fRealTag(tvb, pinfo, subtree, offset, "y-coordinate: "); |
11405 | 413 | } |
11406 | | |
11407 | | static unsigned |
11408 | | // NOLINTNEXTLINE(misc-no-recursion) |
11409 | | fTimerStateChangeValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
11410 | 149 | { |
11411 | 149 | unsigned lastoffset = 0; |
11412 | 149 | uint8_t tag_no, tag_info; |
11413 | 149 | uint32_t lvt; |
11414 | 149 | int32_t save_propertyIdentifier; |
11415 | 149 | unsigned ftag_offset; |
11416 | | |
11417 | 855 | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
11418 | 842 | lastoffset = offset; |
11419 | | /* check the tag. A closing tag means we are done */ |
11420 | 842 | ftag_offset = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11421 | 842 | if (tag_is_closing(tag_info)) { |
11422 | 11 | return offset; |
11423 | 11 | } |
11424 | 831 | if (tag_is_context_specific(tag_info)){ |
11425 | 255 | switch (tag_no) { |
11426 | 79 | case 0: /* no-value */ |
11427 | 79 | offset = fNullTag(tvb, pinfo, tree, offset, "no-value: "); |
11428 | 79 | break; |
11429 | 10 | case 1: /* constructed-value */ |
11430 | 10 | offset += ftag_offset; |
11431 | | /* this ASN-1 construction may contain also an property identifier, so |
11432 | | save the one we have got and restore it later and invalidate current |
11433 | | one to avoid misinterpretations */ |
11434 | 10 | save_propertyIdentifier = propertyIdentifier; |
11435 | 10 | propertyIdentifier = -1; |
11436 | 10 | offset = fAbstractSyntaxNType(tvb, pinfo, tree, offset); |
11437 | 10 | propertyIdentifier = save_propertyIdentifier; |
11438 | 10 | offset += fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11439 | 10 | break; |
11440 | 16 | case 2: /* date-time */ |
11441 | 16 | offset += ftag_offset; |
11442 | 16 | offset = fDateTime(tvb, pinfo, tree, offset, "date-time: "); |
11443 | 16 | offset += fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11444 | 16 | break; |
11445 | 29 | case 3: /* lighting-command */ |
11446 | 29 | offset += ftag_offset; |
11447 | 29 | offset = fLightingCommand(tvb, pinfo, tree, offset, "lighting-command: "); |
11448 | 29 | offset += fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11449 | 29 | break; |
11450 | 121 | default: |
11451 | 121 | return offset; |
11452 | 255 | } |
11453 | 255 | } |
11454 | 576 | else { |
11455 | 576 | offset = fApplicationTypes(tvb, pinfo, tree, offset, NULL); |
11456 | 576 | } |
11457 | 831 | } |
11458 | 13 | return offset; |
11459 | 149 | } |
11460 | | |
11461 | | static unsigned |
11462 | | fHostAddress(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
11463 | 667 | { |
11464 | 667 | uint8_t tag_no, tag_info; |
11465 | 667 | uint32_t lvt; |
11466 | | |
11467 | 667 | if (tvb_reported_length_remaining(tvb, offset) > 0) { |
11468 | 666 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11469 | 666 | switch (tag_no) { |
11470 | 569 | case 0: /* none */ |
11471 | 569 | offset = fNullTag(tvb, pinfo, tree, offset, "no-value: "); |
11472 | 569 | break; |
11473 | 11 | case 1: /* ip-address */ |
11474 | 11 | offset = fOctetString(tvb, pinfo, tree, offset, "ip-address: ", lvt); |
11475 | 11 | break; |
11476 | 11 | case 2: /* internet name (see RFC 1123) */ |
11477 | 11 | offset = fCharacterString(tvb, pinfo, tree, offset, "name: "); |
11478 | 11 | break; |
11479 | 75 | default: |
11480 | 75 | return offset; |
11481 | 666 | } |
11482 | 666 | } |
11483 | | |
11484 | 591 | return offset; |
11485 | 667 | } |
11486 | | |
11487 | | static unsigned |
11488 | | fHostNPort(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *lable) |
11489 | 446 | { |
11490 | 446 | unsigned lastoffset = 0; |
11491 | 446 | uint8_t tag_no, tag_info; |
11492 | 446 | uint32_t lvt; |
11493 | 446 | proto_tree *subtree = tree; |
11494 | | |
11495 | 446 | subtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0, |
11496 | 446 | ett_bacapp_value, NULL, "%s", lable); |
11497 | | |
11498 | 1.25k | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
11499 | 1.25k | lastoffset = offset; |
11500 | | /* check the tag. A closing tag means we are done */ |
11501 | 1.25k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11502 | 1.25k | if (tag_is_closing(tag_info)) { |
11503 | 23 | return offset; |
11504 | 23 | } |
11505 | 1.22k | switch (tag_no) { |
11506 | 667 | case 0: /* host */ |
11507 | 667 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11508 | 667 | offset = fHostAddress(tvb, pinfo, subtree, offset); |
11509 | 667 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11510 | 667 | break; |
11511 | 142 | case 1: /* port */ |
11512 | 142 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "port: "); |
11513 | 142 | break; |
11514 | 420 | default: |
11515 | 420 | return offset; |
11516 | 1.22k | } |
11517 | 1.22k | } |
11518 | | |
11519 | 1 | return offset; |
11520 | 446 | } |
11521 | | |
11522 | | static unsigned |
11523 | | fBDTEntry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *lable) |
11524 | 97 | { |
11525 | 97 | unsigned lastoffset = 0; |
11526 | 97 | uint8_t tag_no, tag_info; |
11527 | 97 | uint32_t lvt; |
11528 | 97 | proto_tree *subtree = tree; |
11529 | | |
11530 | 97 | subtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0, |
11531 | 97 | ett_bacapp_value, NULL, "%s", lable); |
11532 | | |
11533 | 322 | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
11534 | 321 | lastoffset = offset; |
11535 | | /* check the tag. A closing tag means we are done */ |
11536 | 321 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11537 | 321 | if (tag_is_closing(tag_info)) { |
11538 | 18 | return offset; |
11539 | 18 | } |
11540 | | |
11541 | 303 | switch (tag_no) { |
11542 | 195 | case 0: /* bbmd-address */ |
11543 | 195 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11544 | 195 | offset = fHostNPort(tvb, pinfo, subtree, offset, "bbmd-address: "); |
11545 | 195 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11546 | 195 | break; |
11547 | 32 | case 1: /* bbmd-mask */ |
11548 | 32 | offset = fOctetString(tvb, pinfo, subtree, offset, "bbmd-mask: ", lvt); |
11549 | 32 | break; |
11550 | 76 | default: |
11551 | 76 | return offset; |
11552 | 303 | } |
11553 | 303 | } |
11554 | | |
11555 | 1 | return offset; |
11556 | 97 | } |
11557 | | |
11558 | | static unsigned |
11559 | | fFDTEntry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *lable) |
11560 | 66 | { |
11561 | 66 | unsigned lastoffset = 0; |
11562 | 66 | uint8_t tag_no, tag_info; |
11563 | 66 | uint32_t lvt; |
11564 | 66 | proto_tree *subtree = tree; |
11565 | | |
11566 | 66 | subtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0, |
11567 | 66 | ett_bacapp_value, NULL, "%s", lable); |
11568 | | |
11569 | 304 | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
11570 | 304 | lastoffset = offset; |
11571 | | /* check the tag. A closing tag means we are done */ |
11572 | 304 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11573 | 304 | if (tag_is_closing(tag_info)) { |
11574 | 4 | return offset; |
11575 | 4 | } |
11576 | | |
11577 | 300 | switch (tag_no) { |
11578 | 200 | case 0: /* bacnetip-address */ |
11579 | 200 | offset = fOctetString(tvb, pinfo, subtree, offset, "bacnetip-address: ", lvt); |
11580 | 200 | break; |
11581 | 8 | case 1: /* time-to-live */ |
11582 | 8 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "time-to-live: "); |
11583 | 8 | break; |
11584 | 30 | case 2: /* remaining-time-to-live */ |
11585 | 30 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "remaining-time-to-live: "); |
11586 | 30 | break; |
11587 | 62 | default: |
11588 | 62 | return offset; |
11589 | 300 | } |
11590 | 300 | } |
11591 | | |
11592 | 0 | return offset; |
11593 | 66 | } |
11594 | | |
11595 | | static unsigned |
11596 | | fRouterEntry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
11597 | 87 | { |
11598 | 87 | unsigned lastoffset = 0; |
11599 | 87 | uint8_t tag_no, tag_info; |
11600 | 87 | uint32_t lvt; |
11601 | | |
11602 | 1.00k | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
11603 | 999 | lastoffset = offset; |
11604 | | /* check the tag. A closing tag means we are done */ |
11605 | 999 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11606 | 999 | if (tag_is_closing(tag_info)) { |
11607 | 13 | break; |
11608 | 13 | } |
11609 | 986 | switch (tag_no) { |
11610 | 286 | case 0: /* network number */ |
11611 | 286 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "network number: "); |
11612 | 286 | break; |
11613 | 395 | case 1: /* MAC address */ |
11614 | 395 | offset = fOctetString(tvb, pinfo, tree, offset, "MAC address: ", lvt); |
11615 | 395 | break; |
11616 | 108 | case 2: /* status */ |
11617 | 108 | offset = fEnumeratedTag(tvb, pinfo, tree, offset, "status: ", BACnetRouterStatus); |
11618 | 108 | break; |
11619 | 128 | case 3: /* performance index */ |
11620 | 128 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "performance index: "); |
11621 | 128 | break; |
11622 | 68 | default: |
11623 | 68 | return offset; |
11624 | 986 | } |
11625 | 917 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
11626 | 917 | } |
11627 | | |
11628 | 18 | return offset; |
11629 | 87 | } |
11630 | | |
11631 | | static unsigned |
11632 | | fVMACEntry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
11633 | 45 | { |
11634 | 45 | unsigned lastoffset = 0; |
11635 | 45 | uint8_t tag_no, tag_info; |
11636 | 45 | uint32_t lvt; |
11637 | | |
11638 | 194 | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
11639 | 190 | lastoffset = offset; |
11640 | | /* check the tag. A closing tag means we are done */ |
11641 | 190 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11642 | 190 | if (tag_is_closing(tag_info)) { |
11643 | 3 | break; |
11644 | 3 | } |
11645 | 187 | switch (tag_no) { |
11646 | 102 | case 0: /* virtual mac address */ |
11647 | 102 | offset = fOctetString(tvb, pinfo, tree, offset, "virtual MAC address: ", lvt); |
11648 | 102 | break; |
11649 | 47 | case 1: /* native mac address */ |
11650 | 47 | offset = fOctetString(tvb, pinfo, tree, offset, "native MAC address: ", lvt); |
11651 | 47 | break; |
11652 | 38 | default: |
11653 | 38 | return offset; |
11654 | 187 | } |
11655 | 149 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
11656 | 149 | } |
11657 | | |
11658 | 7 | return offset; |
11659 | 45 | } |
11660 | | |
11661 | | static unsigned |
11662 | | fValueSource(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
11663 | 1.46k | { |
11664 | 1.46k | uint8_t tag_no, tag_info; |
11665 | 1.46k | uint32_t lvt; |
11666 | | |
11667 | 1.46k | if (tvb_reported_length_remaining(tvb, offset) > 0) { |
11668 | 1.46k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11669 | 1.46k | switch (tag_no) { |
11670 | 1.15k | case 0: /* null */ |
11671 | 1.15k | offset = fNullTag(tvb, pinfo, tree, offset, "no-value: "); |
11672 | 1.15k | break; |
11673 | 70 | case 1: /* object reference */ |
11674 | 70 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
11675 | 70 | offset = fDeviceObjectReference(tvb, pinfo, tree, offset); |
11676 | 70 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
11677 | 70 | break; |
11678 | 165 | case 2: /* address */ |
11679 | 165 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
11680 | 165 | offset = fAddress(tvb, pinfo, tree, offset); |
11681 | 165 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
11682 | 165 | break; |
11683 | 78 | default: |
11684 | 78 | return offset; |
11685 | 1.46k | } |
11686 | 1.46k | } |
11687 | | |
11688 | 1.37k | return offset; |
11689 | 1.46k | } |
11690 | | |
11691 | | static unsigned |
11692 | | fAssignedLandingCalls(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
11693 | 2.71k | { |
11694 | 2.71k | unsigned lastoffset = 0; |
11695 | 2.71k | uint8_t tag_no, tag_info; |
11696 | 2.71k | uint32_t lvt; |
11697 | | |
11698 | 2.71k | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
11699 | | |
11700 | 3.87k | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
11701 | 3.86k | lastoffset = offset; |
11702 | | /* check the tag. A closing tag means we are done */ |
11703 | 3.86k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11704 | 3.86k | if (tag_is_closing(tag_info)) { |
11705 | 110 | break; |
11706 | 110 | } |
11707 | 3.75k | switch (tag_no) { |
11708 | 909 | case 0: /* floor number */ |
11709 | 909 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "floor number: "); |
11710 | 909 | break; |
11711 | 260 | case 1: /* direction */ |
11712 | 260 | offset = fEnumeratedTag(tvb, pinfo, tree, offset, "direction: ", BACnetLiftCarDirection); |
11713 | 260 | break; |
11714 | 2.58k | default: |
11715 | 2.58k | return offset; |
11716 | 3.75k | } |
11717 | 1.16k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
11718 | 1.16k | } |
11719 | | |
11720 | 124 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
11721 | 124 | return offset; |
11722 | 2.71k | } |
11723 | | |
11724 | | static unsigned |
11725 | | fLandingCallStatus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
11726 | 181 | { |
11727 | 181 | unsigned lastoffset = 0; |
11728 | 181 | uint8_t tag_no, tag_info; |
11729 | 181 | uint32_t lvt; |
11730 | | |
11731 | 2.52k | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
11732 | 2.52k | lastoffset = offset; |
11733 | | /* check the tag. A closing tag means we are done */ |
11734 | 2.52k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11735 | 2.52k | if (tag_is_closing(tag_info)) { |
11736 | 34 | break; |
11737 | 34 | } |
11738 | 2.48k | switch (tag_no) { |
11739 | 1.28k | case 0: /* floor number */ |
11740 | 1.28k | offset = fUnsignedTag(tvb, pinfo, tree, offset, "floor number: "); |
11741 | 1.28k | break; |
11742 | 609 | case 1: /* direction */ |
11743 | 609 | offset = fEnumeratedTag(tvb, pinfo, tree, offset, "direction: ", BACnetLiftCarDirection); |
11744 | 609 | break; |
11745 | 307 | case 2: /* destination */ |
11746 | 307 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "destination: "); |
11747 | 307 | break; |
11748 | 153 | case 3: /* floor-text */ |
11749 | 153 | offset = fCharacterString(tvb, pinfo, tree, offset, "floor-text: "); |
11750 | 153 | break; |
11751 | 138 | default: |
11752 | 138 | return offset; |
11753 | 2.48k | } |
11754 | 2.34k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
11755 | 2.34k | } |
11756 | | |
11757 | 36 | return offset; |
11758 | 181 | } |
11759 | | |
11760 | | static unsigned |
11761 | | fLandingDoorStatus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
11762 | 827 | { |
11763 | 827 | unsigned lastoffset = 0; |
11764 | 827 | uint8_t tag_no, tag_info; |
11765 | 827 | uint32_t lvt; |
11766 | | |
11767 | 827 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
11768 | | |
11769 | 1.56k | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
11770 | 1.55k | lastoffset = offset; |
11771 | | /* check the tag. A closing tag means we are done */ |
11772 | 1.55k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11773 | 1.55k | if (tag_is_closing(tag_info)) { |
11774 | 39 | break; |
11775 | 39 | } |
11776 | 1.52k | switch (tag_no) { |
11777 | 638 | case 0: /* floor number */ |
11778 | 638 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "floor number: "); |
11779 | 638 | break; |
11780 | 102 | case 1: /* door status */ |
11781 | 102 | offset = fEnumeratedTag(tvb, pinfo, tree, offset, "door status: ", BACnetDoorStatus); |
11782 | 102 | break; |
11783 | 780 | default: |
11784 | 780 | return offset; |
11785 | 1.52k | } |
11786 | 740 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
11787 | 740 | } |
11788 | | |
11789 | 47 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
11790 | 47 | return offset; |
11791 | 827 | } |
11792 | | |
11793 | | static unsigned |
11794 | | fCOVMultipleSubscription(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
11795 | 404 | { |
11796 | 404 | unsigned lastoffset = 0; |
11797 | 404 | uint8_t tag_no, tag_info; |
11798 | 404 | uint32_t lvt; |
11799 | | |
11800 | 1.07k | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
11801 | 1.07k | lastoffset = offset; |
11802 | | /* check the tag. A closing tag means we are done */ |
11803 | 1.07k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11804 | 1.07k | if (tag_is_closing(tag_info)) { |
11805 | 11 | break; |
11806 | 11 | } |
11807 | 1.05k | switch (tag_no) { |
11808 | 111 | case 0: /* recipient */ |
11809 | 111 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
11810 | 111 | offset = fRecipientProcess(tvb, pinfo, tree, offset); |
11811 | 111 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
11812 | 111 | break; |
11813 | 208 | case 1: /* issue-confirmed-notifications */ |
11814 | 208 | offset = fBooleanTag(tvb, pinfo, tree, offset, "issue confirmed notifications: "); |
11815 | 208 | break; |
11816 | 125 | case 2: /* time-remaining */ |
11817 | 125 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "time remaining: "); |
11818 | 125 | break; |
11819 | 224 | case 3: /* max-notification-delay */ |
11820 | 224 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "max notification delay: "); |
11821 | 224 | break; |
11822 | 329 | case 4: /* list-of-cov-subscription-specifications */ |
11823 | 329 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
11824 | 754 | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
11825 | 750 | lastoffset = offset; |
11826 | | /* check the tag. A closing tag means we are done */ |
11827 | 750 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11828 | 750 | if (tag_is_closing(tag_info)) { |
11829 | 11 | break; |
11830 | 11 | } |
11831 | 739 | switch (tag_no) { |
11832 | 393 | case 0: /* monitored-object-identifier */ |
11833 | 393 | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_object_identifier); |
11834 | 393 | break; |
11835 | 79 | case 1: /* list-of-cov-references */ |
11836 | 79 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
11837 | 406 | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
11838 | 404 | lastoffset = offset; |
11839 | | /* check the tag. A closing tag means we are done */ |
11840 | 404 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11841 | 404 | if (tag_is_closing(tag_info)) { |
11842 | 32 | break; |
11843 | 32 | } |
11844 | 372 | switch (tag_no) { |
11845 | 127 | case 0: /* monitored-property */ |
11846 | 127 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
11847 | 127 | offset = fBACnetPropertyReference(tvb, pinfo, tree, offset, 0); |
11848 | 127 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
11849 | 127 | break; |
11850 | 38 | case 1: /* cov-increment */ |
11851 | 38 | offset = fRealTag(tvb, pinfo, tree, offset, "cov-increment: "); |
11852 | 38 | break; |
11853 | 163 | case 2: /* timestamped */ |
11854 | 163 | offset = fBooleanTag(tvb, pinfo, tree, offset, "timestamped: "); |
11855 | 163 | break; |
11856 | 44 | default: |
11857 | 44 | return offset; |
11858 | 372 | } |
11859 | 327 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
11860 | 327 | } |
11861 | 34 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
11862 | 34 | break; |
11863 | 267 | default: |
11864 | 267 | return offset; |
11865 | 739 | } |
11866 | 425 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
11867 | 425 | } |
11868 | 15 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
11869 | 15 | break; |
11870 | 62 | default: |
11871 | 62 | return offset; |
11872 | 1.05k | } |
11873 | 674 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
11874 | 674 | } |
11875 | | |
11876 | 19 | return offset; |
11877 | 404 | } |
11878 | | |
11879 | | static unsigned |
11880 | | fNameValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
11881 | 1.44k | { |
11882 | 1.44k | unsigned lastoffset = 0; |
11883 | 1.44k | uint8_t tag_no, tag_info; |
11884 | 1.44k | uint32_t lvt; |
11885 | | |
11886 | 3.89k | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
11887 | 3.87k | lastoffset = offset; |
11888 | | /* check the tag. A closing tag means we are done */ |
11889 | 3.87k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11890 | 3.87k | if (tag_is_closing(tag_info)) { |
11891 | 91 | break; |
11892 | 91 | } |
11893 | 3.78k | if (tag_is_context_specific(tag_info)) { |
11894 | 1.44k | switch (tag_no) { |
11895 | 95 | case 0: /* name */ |
11896 | 95 | offset = fCharacterString(tvb, pinfo, tree, offset, "name: "); |
11897 | 95 | break; |
11898 | 49 | case 1: /* date+time value */ |
11899 | 49 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
11900 | 49 | offset = fDateTime(tvb, pinfo, tree, offset, "value: "); |
11901 | 49 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
11902 | 49 | break; |
11903 | 1.30k | default: /* abstract syntax and type */ |
11904 | | /* DMR Should be fAbstractNSyntax, but that's where we came from! */ |
11905 | 1.30k | offset = fApplicationTypes(tvb, pinfo, tree, offset, "value: "); |
11906 | 1.30k | break; |
11907 | 1.44k | } |
11908 | 1.44k | } |
11909 | 2.34k | else { |
11910 | | /* DMR Should be fAbstractNSyntax, but that's where we came from! */ |
11911 | 2.34k | offset = fApplicationTypes(tvb, pinfo, tree, offset, "value: "); |
11912 | 2.34k | } |
11913 | 3.78k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
11914 | 3.78k | } |
11915 | 1.43k | return offset; |
11916 | 1.44k | } |
11917 | | |
11918 | | static unsigned |
11919 | | fNameValueCollection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
11920 | 1.18k | { |
11921 | 1.18k | unsigned lastoffset = 0; |
11922 | 1.18k | uint8_t tag_no, tag_info; |
11923 | 1.18k | uint32_t lvt; |
11924 | 1.18k | proto_tree *subtree = tree; |
11925 | | |
11926 | 1.18k | subtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0, |
11927 | 1.18k | ett_bacapp_value, NULL, "%s", "name-value-collection: "); |
11928 | | |
11929 | 1.18k | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11930 | | |
11931 | 2.62k | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
11932 | 1.55k | lastoffset = offset; |
11933 | | /* check the tag. A closing tag means we are done */ |
11934 | 1.55k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11935 | 1.55k | if (tag_is_closing(tag_info)) { |
11936 | 113 | break; |
11937 | 113 | } |
11938 | | |
11939 | 1.44k | offset = fNameValue(tvb, pinfo, subtree, offset); |
11940 | 1.44k | } |
11941 | | |
11942 | 1.18k | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
11943 | 1.18k | return offset; |
11944 | 1.18k | } |
11945 | | |
11946 | | static unsigned |
11947 | | fObjectSelector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
11948 | 44 | { |
11949 | 44 | unsigned lastoffset = 0; |
11950 | 44 | uint8_t tag_no, tag_info; |
11951 | 44 | uint32_t lvt; |
11952 | | |
11953 | 148 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
11954 | 148 | lastoffset = offset; |
11955 | 148 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11956 | 148 | if (tag_is_closing(tag_info)) { |
11957 | 3 | break; |
11958 | 3 | } |
11959 | | |
11960 | 145 | switch (tag_no) { |
11961 | 75 | case 0: /* NULL */ |
11962 | 75 | offset = fNullTag(tvb, pinfo, tree, offset, "NULL: "); |
11963 | 75 | break; |
11964 | 2 | case 9: /* object-type */ |
11965 | 2 | offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset, "object-type: ", BACnetObjectType, 256); |
11966 | 2 | break; |
11967 | 27 | case 12: /* object */ |
11968 | 27 | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_object_identifier); |
11969 | 27 | break; |
11970 | 41 | default: |
11971 | 41 | break; |
11972 | 145 | } |
11973 | 145 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
11974 | 145 | } |
11975 | 44 | return offset; |
11976 | 44 | } |
11977 | | |
11978 | | static unsigned |
11979 | | fDeviceAddressProxyTableEntry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *lable) |
11980 | 0 | { |
11981 | 0 | unsigned lastoffset = 0; |
11982 | 0 | uint8_t tag_no, tag_info; |
11983 | 0 | uint32_t lvt; |
11984 | 0 | proto_tree *subtree = tree; |
11985 | |
|
11986 | 0 | subtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0, |
11987 | 0 | ett_bacapp_value, NULL, "%s", lable); |
11988 | |
|
11989 | 0 | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
11990 | 0 | lastoffset = offset; |
11991 | | /* check the tag. A closing tag means we are done */ |
11992 | 0 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
11993 | 0 | if (tag_is_closing(tag_info)) { |
11994 | 0 | return offset; |
11995 | 0 | } |
11996 | | |
11997 | 0 | switch (tag_no) { |
11998 | 0 | case 0: /* address */ |
11999 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12000 | 0 | offset = fAddress(tvb, pinfo, subtree, offset); |
12001 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12002 | 0 | break; |
12003 | 0 | case 1: /* i-am */ |
12004 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12005 | 0 | offset = fIAmRequest(tvb, pinfo, subtree, offset); |
12006 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12007 | 0 | break; |
12008 | 0 | case 2: /* last-i-am-time */ |
12009 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12010 | 0 | offset = fDateTime(tvb, pinfo, subtree, offset, "issued: "); |
12011 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12012 | 0 | break; |
12013 | 0 | default: |
12014 | 0 | break; |
12015 | 0 | } |
12016 | 0 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
12017 | 0 | } |
12018 | | |
12019 | 0 | return offset; |
12020 | 0 | } |
12021 | | |
12022 | | static unsigned |
12023 | | fAccessToken(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *lable) |
12024 | 369 | { |
12025 | 369 | unsigned lastoffset = 0; |
12026 | 369 | uint8_t tag_no, tag_info; |
12027 | 369 | uint32_t lvt; |
12028 | 369 | proto_tree *subtree = tree; |
12029 | 369 | proto_tree *subsubtree = tree; |
12030 | | |
12031 | 369 | subtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0, |
12032 | 369 | ett_bacapp_value, NULL, "%s", lable); |
12033 | | |
12034 | 4.68k | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
12035 | 4.67k | lastoffset = offset; |
12036 | | /* check the tag. A closing tag means we are done */ |
12037 | 4.67k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
12038 | 4.67k | if (tag_is_closing(tag_info)) { |
12039 | 113 | return offset; |
12040 | 113 | } |
12041 | | |
12042 | 4.55k | switch (tag_no) { |
12043 | 2.45k | case 0: /* issuer */ |
12044 | 2.45k | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "issuer: "); |
12045 | 2.45k | break; |
12046 | 123 | case 1: /* issued */ |
12047 | 123 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12048 | 123 | offset = fDateTime(tvb, pinfo, subtree, offset, "issued: "); |
12049 | 123 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12050 | 123 | break; |
12051 | 104 | case 2: /* audience */ |
12052 | 104 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12053 | 104 | subsubtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0, |
12054 | 104 | ett_bacapp_value, NULL, "%s", "audience:"); |
12055 | | |
12056 | 1.35k | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
12057 | 1.32k | lastoffset = offset; |
12058 | | /* check the tag. A closing tag means we are done */ |
12059 | 1.32k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
12060 | 1.32k | if (tag_is_closing(tag_info)) { |
12061 | 76 | break; |
12062 | 76 | } |
12063 | | |
12064 | 1.24k | offset = fSignedTag(tvb, pinfo, subsubtree, offset, "listener: "); |
12065 | 1.24k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
12066 | 1.24k | } |
12067 | 104 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12068 | 104 | break; |
12069 | 153 | case 3: /* not-before */ |
12070 | 153 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12071 | 153 | offset = fDateTime(tvb, pinfo, subtree, offset, "not-before: "); |
12072 | 153 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12073 | 153 | break; |
12074 | 212 | case 4: /* not-after */ |
12075 | 212 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12076 | 212 | offset = fDateTime(tvb, pinfo, subtree, offset, "not-after: "); |
12077 | 212 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12078 | 212 | break; |
12079 | 171 | case 5: /* client */ |
12080 | 171 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "client: "); |
12081 | 171 | break; |
12082 | 527 | case 6: /* constraint */ |
12083 | 527 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12084 | 527 | offset = fAuthorizationConstraint(tvb, pinfo, subtree, offset, "constraint: "); |
12085 | 527 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12086 | 527 | break; |
12087 | 53 | case 7: /* scope */ |
12088 | 53 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12089 | 53 | offset = fAuthorizationScope(tvb, pinfo, subtree, offset, "scope: "); |
12090 | 53 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12091 | 53 | break; |
12092 | 366 | case 8: /* key-id */ |
12093 | 366 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "key-id: "); |
12094 | 366 | break; |
12095 | 231 | case 9: /* signature */ |
12096 | 231 | offset = fOctetString(tvb, pinfo, subtree, offset, "signature", lvt); |
12097 | 231 | break; |
12098 | 165 | default: |
12099 | 165 | break; |
12100 | 4.55k | } |
12101 | 4.48k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
12102 | 4.48k | } |
12103 | | |
12104 | 180 | return offset; |
12105 | 369 | } |
12106 | | |
12107 | | unsigned |
12108 | | bacnet_dissect_token(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, |
12109 | | unsigned offset, const char *lable) |
12110 | 0 | { |
12111 | 0 | return fAccessToken(tvb, pinfo, tree, offset, lable); |
12112 | 0 | } |
12113 | | |
12114 | | static unsigned |
12115 | | fAuthenticationClient(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *lable) |
12116 | 0 | { |
12117 | 0 | unsigned lastoffset = 0; |
12118 | 0 | uint8_t tag_no, tag_info; |
12119 | 0 | uint32_t lvt; |
12120 | 0 | proto_tree *subtree = tree; |
12121 | |
|
12122 | 0 | subtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0, |
12123 | 0 | ett_bacapp_value, NULL, "%s", lable); |
12124 | |
|
12125 | 0 | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
12126 | 0 | lastoffset = offset; |
12127 | | /* check the tag. A closing tag means we are done */ |
12128 | 0 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
12129 | 0 | if (tag_is_closing(tag_info)) { |
12130 | 0 | return offset; |
12131 | 0 | } |
12132 | | |
12133 | 0 | offset = fBooleanTag(tvb, pinfo, subtree, offset, "authenticated: "); |
12134 | 0 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "device: "); |
12135 | 0 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
12136 | 0 | } |
12137 | | |
12138 | 0 | return offset; |
12139 | 0 | } |
12140 | | |
12141 | | static unsigned |
12142 | | fAuthorizationEvent(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *lable) |
12143 | 0 | { |
12144 | 0 | unsigned lastoffset = 0; |
12145 | 0 | uint8_t tag_no, tag_info; |
12146 | 0 | uint32_t lvt; |
12147 | 0 | proto_tree *subtree = tree; |
12148 | |
|
12149 | 0 | subtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0, |
12150 | 0 | ett_bacapp_value, NULL, "%s", lable); |
12151 | |
|
12152 | 0 | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
12153 | 0 | lastoffset = offset; |
12154 | | /* check the tag. A closing tag means we are done */ |
12155 | 0 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
12156 | 0 | if (tag_is_closing(tag_info)) { |
12157 | 0 | return offset; |
12158 | 0 | } |
12159 | | |
12160 | 0 | switch (tag_no) { |
12161 | 0 | case 0: /* time-stamp */ |
12162 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12163 | 0 | offset = fDateTime(tvb, pinfo, subtree, offset, "time-stamp: "); |
12164 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12165 | 0 | break; |
12166 | 0 | case 1: /* address */ |
12167 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12168 | 0 | offset = fAddress(tvb, pinfo, subtree, offset); |
12169 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12170 | 0 | break; |
12171 | 0 | case 2: /* client */ |
12172 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12173 | 0 | offset = fAuthenticationClient(tvb, pinfo, subtree, offset, "client: "); |
12174 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12175 | 0 | break; |
12176 | 0 | case 3: /* token */ |
12177 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12178 | 0 | offset = fAccessToken(tvb, pinfo, subtree, offset, "token: "); |
12179 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12180 | 0 | break; |
12181 | 0 | case 4: /* decision */ |
12182 | 0 | offset = fApplicationTypesEnumerated(tvb, pinfo, subtree, offset, "decision: ", BACnetAuthorizationDecision); |
12183 | 0 | break; |
12184 | 0 | case 5: /* decision-details */ |
12185 | 0 | offset = fCharacterString(tvb, pinfo, subtree, offset, "decision-details: "); |
12186 | 0 | break; |
12187 | 0 | default: |
12188 | 0 | break; |
12189 | 0 | } |
12190 | 0 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
12191 | 0 | } |
12192 | | |
12193 | 0 | return offset; |
12194 | 0 | } |
12195 | | |
12196 | | static unsigned |
12197 | | fAuthenticationPeer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *lable) |
12198 | 0 | { |
12199 | 0 | unsigned lastoffset = 0; |
12200 | 0 | uint8_t tag_no, tag_info; |
12201 | 0 | uint32_t lvt; |
12202 | 0 | proto_tree *subtree = tree; |
12203 | |
|
12204 | 0 | subtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0, |
12205 | 0 | ett_bacapp_value, NULL, "%s", lable); |
12206 | |
|
12207 | 0 | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
12208 | 0 | lastoffset = offset; |
12209 | | /* check the tag. A closing tag means we are done */ |
12210 | 0 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
12211 | 0 | if (tag_is_closing(tag_info)) { |
12212 | 0 | return offset; |
12213 | 0 | } |
12214 | | |
12215 | 0 | switch (tag_no) { |
12216 | 0 | case 0: /* host */ |
12217 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12218 | 0 | offset = fHostNPort(tvb, pinfo, subtree, offset, "host: "); |
12219 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12220 | 0 | break; |
12221 | 0 | default: |
12222 | 0 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "device: "); |
12223 | 0 | offset = fBooleanTag(tvb, pinfo, subtree, offset, "auth-aware: "); |
12224 | 0 | offset = fBooleanTag(tvb, pinfo, subtree, offset, "router: "); |
12225 | 0 | offset = fBooleanTag(tvb, pinfo, subtree, offset, "hub: "); |
12226 | 0 | break; |
12227 | 0 | } |
12228 | 0 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
12229 | 0 | } |
12230 | | |
12231 | 0 | return offset; |
12232 | 0 | } |
12233 | | |
12234 | | static unsigned |
12235 | | fAuthenticationEvent(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *lable) |
12236 | 0 | { |
12237 | 0 | unsigned lastoffset = 0; |
12238 | 0 | uint8_t tag_no, tag_info; |
12239 | 0 | uint32_t lvt; |
12240 | 0 | proto_tree *subtree = tree; |
12241 | |
|
12242 | 0 | subtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0, |
12243 | 0 | ett_bacapp_value, NULL, "%s", lable); |
12244 | |
|
12245 | 0 | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
12246 | 0 | lastoffset = offset; |
12247 | | /* check the tag. A closing tag means we are done */ |
12248 | 0 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
12249 | 0 | if (tag_is_closing(tag_info)) { |
12250 | 0 | return offset; |
12251 | 0 | } |
12252 | | |
12253 | 0 | switch (tag_no) { |
12254 | 0 | case 0: /* time-stamp */ |
12255 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12256 | 0 | offset = fDateTime(tvb, pinfo, subtree, offset, "time-stamp: "); |
12257 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12258 | 0 | break; |
12259 | 0 | case 1: /* peer */ |
12260 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12261 | 0 | offset = fAuthenticationPeer(tvb, pinfo, subtree, offset, "peer: "); |
12262 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12263 | 0 | break; |
12264 | 0 | case 2: /* client */ |
12265 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12266 | 0 | offset = fAuthenticationClient(tvb, pinfo, subtree, offset, "client: "); |
12267 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12268 | 0 | break; |
12269 | 0 | case 3: /* decision */ |
12270 | 0 | offset = fApplicationTypesEnumerated(tvb, pinfo, subtree, offset, "decision: ", BACnetAuthenticationDecision); |
12271 | 0 | break; |
12272 | 0 | case 4: /* decision-details */ |
12273 | 0 | offset = fCharacterString(tvb, pinfo, subtree, offset, "decision-details: "); |
12274 | 0 | break; |
12275 | 0 | default: |
12276 | 0 | break; |
12277 | 0 | } |
12278 | 0 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
12279 | 0 | } |
12280 | | |
12281 | 0 | return offset; |
12282 | 0 | } |
12283 | | |
12284 | | static unsigned |
12285 | | fAuthorizationPolicy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *lable) |
12286 | 0 | { |
12287 | 0 | unsigned lastoffset = 0; |
12288 | 0 | uint8_t tag_no, tag_info; |
12289 | 0 | uint32_t lvt; |
12290 | 0 | proto_tree *subtree = tree; |
12291 | 0 | proto_tree *subsubtree = tree; |
12292 | |
|
12293 | 0 | subtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0, |
12294 | 0 | ett_bacapp_value, NULL, "%s", lable); |
12295 | |
|
12296 | 0 | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
12297 | 0 | lastoffset = offset; |
12298 | | /* check the tag. A closing tag means we are done */ |
12299 | 0 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
12300 | 0 | if (tag_is_closing(tag_info)) { |
12301 | 0 | return offset; |
12302 | 0 | } |
12303 | | |
12304 | 0 | switch (tag_no) { |
12305 | 0 | case 0: /* not-before */ |
12306 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12307 | 0 | offset = fDateTime(tvb, pinfo, subtree, offset, "not-before: "); |
12308 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12309 | 0 | break; |
12310 | 0 | case 1: /* not-after */ |
12311 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12312 | 0 | offset = fDateTime(tvb, pinfo, subtree, offset, "not-after: "); |
12313 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12314 | 0 | break; |
12315 | 0 | case 2: /* clients */ |
12316 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12317 | 0 | subsubtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0, |
12318 | 0 | ett_bacapp_value, NULL, "%s", "clients:"); |
12319 | |
|
12320 | 0 | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
12321 | 0 | lastoffset = offset; |
12322 | | /* check the tag. A closing tag means we are done */ |
12323 | 0 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
12324 | 0 | if (tag_is_closing(tag_info)) { |
12325 | 0 | break; |
12326 | 0 | } |
12327 | | |
12328 | 0 | offset = fApplicationTypes(tvb, pinfo, subsubtree, offset, "client: "); |
12329 | 0 | } |
12330 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12331 | 0 | break; |
12332 | 0 | case 3: /* constraint */ |
12333 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12334 | 0 | offset = fAuthorizationConstraint(tvb, pinfo, subtree, offset, "constraint: "); |
12335 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12336 | 0 | break; |
12337 | 0 | case 4: /* scope */ |
12338 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12339 | 0 | offset = fAuthorizationScope(tvb, pinfo, subtree, offset, "scope: "); |
12340 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12341 | 0 | break; |
12342 | 0 | default: |
12343 | 0 | break; |
12344 | 0 | } |
12345 | 0 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
12346 | 0 | } |
12347 | | |
12348 | 0 | return offset; |
12349 | 0 | } |
12350 | | |
12351 | | static unsigned |
12352 | | fAuthorizationConstraint(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *lable) |
12353 | 527 | { |
12354 | 527 | unsigned lastoffset = 0; |
12355 | 527 | uint8_t tag_no, tag_info; |
12356 | 527 | uint32_t lvt; |
12357 | 527 | proto_tree *subtree = tree; |
12358 | | |
12359 | 527 | subtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0, |
12360 | 527 | ett_bacapp_value, NULL, "%s", lable); |
12361 | | |
12362 | 1.27k | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
12363 | 1.25k | lastoffset = offset; |
12364 | | /* check the tag. A closing tag means we are done */ |
12365 | 1.25k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
12366 | 1.25k | if (tag_is_closing(tag_info)) { |
12367 | 24 | return offset; |
12368 | 24 | } |
12369 | | |
12370 | 1.22k | offset = fApplicationTypesEnumerated(tvb, pinfo, subtree, offset, "origin: ", BACnetAuthorizationConstraintOrigin); |
12371 | 1.22k | offset = fApplicationTypesEnumerated(tvb, pinfo, subtree, offset, "authentication: ", BACnetAuthorizationConstraintAuthentication); |
12372 | 1.22k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
12373 | 1.22k | } |
12374 | | |
12375 | 503 | return offset; |
12376 | 527 | } |
12377 | | |
12378 | | static unsigned |
12379 | | fAuthorizationScope(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *lable) |
12380 | 129 | { |
12381 | 129 | unsigned lastoffset = 0, len; |
12382 | 129 | uint8_t tag_no, tag_info; |
12383 | 129 | uint32_t lvt; |
12384 | 129 | proto_tree *subtree = tree; |
12385 | 129 | proto_tree *subsubtree = tree; |
12386 | | |
12387 | 129 | subtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0, |
12388 | 129 | ett_bacapp_value, NULL, "%s", lable); |
12389 | | |
12390 | 544 | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
12391 | 541 | lastoffset = offset; |
12392 | | /* check the tag. A closing tag means we are done */ |
12393 | 541 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
12394 | 541 | if (tag_is_closing(tag_info)) { |
12395 | 10 | return offset; |
12396 | 10 | } |
12397 | | |
12398 | 531 | switch (tag_no) { |
12399 | 105 | case 0: /* extended */ |
12400 | 105 | if (tag_is_opening(tag_info)) { |
12401 | 7 | subsubtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "extended: "); |
12402 | 7 | offset += fTagHeaderTree(tvb, pinfo, subsubtree, offset, &tag_no, &tag_info, &lvt); |
12403 | | |
12404 | 29 | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { /* exit loop if nothing happens inside */ |
12405 | 23 | lastoffset = offset; |
12406 | 23 | len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
12407 | 23 | if (tag_is_closing(tag_info)) { |
12408 | 1 | fTagHeaderTree(tvb, pinfo, subsubtree, offset, &tag_no, &tag_info, &lvt); |
12409 | 1 | offset += len; |
12410 | 1 | break; |
12411 | 1 | } |
12412 | | |
12413 | 22 | offset = fCharacterString(tvb, pinfo, subsubtree, offset, "scope: "); |
12414 | 22 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
12415 | 22 | } |
12416 | 98 | } else { |
12417 | 98 | expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag); |
12418 | 98 | } |
12419 | 105 | break; |
12420 | 426 | default: /* standard */ |
12421 | 426 | offset = fBitStringTagVS(tvb, pinfo, subtree, offset, "standard: ", BACnetAuthorizationScopeStandard); |
12422 | 426 | break; |
12423 | 531 | } |
12424 | 513 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
12425 | 513 | } |
12426 | | |
12427 | 101 | return offset; |
12428 | 129 | } |
12429 | | |
12430 | | unsigned |
12431 | | bacnet_dissect_scope(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, |
12432 | | unsigned offset, const char *lable) |
12433 | 0 | { |
12434 | 0 | return fAuthorizationScope(tvb, pinfo, tree, offset, lable); |
12435 | 0 | } |
12436 | | |
12437 | | static unsigned |
12438 | | fAuthorizationScopeDescription(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *lable) |
12439 | 0 | { |
12440 | 0 | unsigned lastoffset = 0; |
12441 | 0 | uint8_t tag_no, tag_info; |
12442 | 0 | uint32_t lvt; |
12443 | 0 | proto_tree *subtree = tree; |
12444 | |
|
12445 | 0 | subtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0, |
12446 | 0 | ett_bacapp_value, NULL, "%s", lable); |
12447 | |
|
12448 | 0 | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
12449 | 0 | lastoffset = offset; |
12450 | | /* check the tag. A closing tag means we are done */ |
12451 | 0 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
12452 | 0 | if (tag_is_closing(tag_info)) { |
12453 | 0 | return offset; |
12454 | 0 | } |
12455 | | |
12456 | 0 | offset = fCharacterString(tvb, pinfo, subtree, offset, "name: "); |
12457 | 0 | offset = fCharacterString(tvb, pinfo, subtree, offset, "description: "); |
12458 | 0 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
12459 | 0 | } |
12460 | | |
12461 | 0 | return offset; |
12462 | 0 | } |
12463 | | |
12464 | | static unsigned |
12465 | | fAuthorizationServer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *lable) |
12466 | 0 | { |
12467 | 0 | unsigned lastoffset = 0; |
12468 | 0 | uint8_t tag_no, tag_info; |
12469 | 0 | uint32_t lvt; |
12470 | 0 | proto_tree *subtree = tree; |
12471 | |
|
12472 | 0 | subtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0, |
12473 | 0 | ett_bacapp_value, NULL, "%s", lable); |
12474 | |
|
12475 | 0 | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
12476 | 0 | lastoffset = offset; |
12477 | | /* check the tag. A closing tag means we are done */ |
12478 | 0 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
12479 | 0 | if (tag_is_closing(tag_info)) { |
12480 | 0 | return offset; |
12481 | 0 | } |
12482 | | |
12483 | 0 | switch (tag_no) { |
12484 | 0 | case 0: /* auth-server */ |
12485 | 0 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "auth-server: "); |
12486 | 0 | break; |
12487 | 0 | case 1: /* signing-key #1 */ |
12488 | 0 | offset = fOctetString(tvb, pinfo, subtree, offset, "signing-key #1: ", lvt); |
12489 | 0 | break; |
12490 | 0 | case 2: /* signing-key #2 */ |
12491 | 0 | offset = fOctetString(tvb, pinfo, subtree, offset, "signing-key #2: ", lvt); |
12492 | 0 | break; |
12493 | 0 | default: |
12494 | 0 | break; |
12495 | 0 | } |
12496 | 0 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
12497 | 0 | } |
12498 | | |
12499 | 0 | return offset; |
12500 | 0 | } |
12501 | | |
12502 | | static unsigned |
12503 | | fAuthorizationStatus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *lable) |
12504 | 0 | { |
12505 | 0 | unsigned lastoffset = 0; |
12506 | 0 | uint8_t tag_no, tag_info; |
12507 | 0 | uint32_t lvt; |
12508 | 0 | proto_tree *subtree = tree; |
12509 | |
|
12510 | 0 | subtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0, |
12511 | 0 | ett_bacapp_value, NULL, "%s", lable); |
12512 | |
|
12513 | 0 | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
12514 | 0 | lastoffset = offset; |
12515 | | /* check the tag. A closing tag means we are done */ |
12516 | 0 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
12517 | 0 | if (tag_is_closing(tag_info)) { |
12518 | 0 | return offset; |
12519 | 0 | } |
12520 | | |
12521 | 0 | switch (tag_no) { |
12522 | 0 | case 0: /* posture */ |
12523 | 0 | offset = fApplicationTypesEnumerated(tvb, pinfo, subtree, offset, "posture: ", BACnetAuthorizationPosture); |
12524 | 0 | break; |
12525 | 0 | case 1: /* error */ |
12526 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12527 | 0 | offset = fError(tvb, pinfo, subtree, offset); |
12528 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12529 | 0 | break; |
12530 | 0 | case 2: /* error-source */ |
12531 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12532 | 0 | offset = fObjectPropertyReference(tvb, pinfo, subtree, offset); |
12533 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12534 | 0 | break; |
12535 | 0 | case 3: /* error-details */ |
12536 | 0 | offset = fCharacterString(tvb, pinfo, subtree, offset, "error-details: "); |
12537 | 0 | break; |
12538 | 0 | case 4: /* authentication-success */ |
12539 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12540 | 0 | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
12541 | 0 | lastoffset = offset; |
12542 | | /* check the tag. A closing tag means we are done */ |
12543 | 0 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
12544 | 0 | if (tag_is_closing(tag_info)) { |
12545 | 0 | break; |
12546 | 0 | } |
12547 | | |
12548 | 0 | offset = fAuthenticationEvent(tvb, pinfo, subtree, offset, "authentication-success"); |
12549 | 0 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
12550 | 0 | } |
12551 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12552 | 0 | break; |
12553 | 0 | case 5: /* authentication-failure */ |
12554 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12555 | 0 | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
12556 | 0 | lastoffset = offset; |
12557 | | /* check the tag. A closing tag means we are done */ |
12558 | 0 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
12559 | 0 | if (tag_is_closing(tag_info)) { |
12560 | 0 | break; |
12561 | 0 | } |
12562 | | |
12563 | 0 | offset = fAuthenticationEvent(tvb, pinfo, subtree, offset, "authentication-failure"); |
12564 | 0 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
12565 | 0 | } |
12566 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12567 | 0 | break; |
12568 | 0 | case 6: /* authorization-success */ |
12569 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12570 | 0 | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
12571 | 0 | lastoffset = offset; |
12572 | | /* check the tag. A closing tag means we are done */ |
12573 | 0 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
12574 | 0 | if (tag_is_closing(tag_info)) { |
12575 | 0 | break; |
12576 | 0 | } |
12577 | | |
12578 | 0 | offset = fAuthorizationEvent(tvb, pinfo, subtree, offset, "authorization-success"); |
12579 | 0 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
12580 | 0 | } |
12581 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12582 | 0 | break; |
12583 | 0 | case 7: /* authorization-failure */ |
12584 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12585 | 0 | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
12586 | 0 | lastoffset = offset; |
12587 | | /* check the tag. A closing tag means we are done */ |
12588 | 0 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
12589 | 0 | if (tag_is_closing(tag_info)) { |
12590 | 0 | break; |
12591 | 0 | } |
12592 | | |
12593 | 0 | offset = fAuthorizationEvent(tvb, pinfo, subtree, offset, "authorization-failure"); |
12594 | 0 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
12595 | 0 | } |
12596 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12597 | 0 | break; |
12598 | 0 | default: |
12599 | 0 | break; |
12600 | 0 | } |
12601 | 0 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
12602 | 0 | } |
12603 | | |
12604 | 0 | return offset; |
12605 | 0 | } |
12606 | | |
12607 | | static unsigned |
12608 | | fStageLimitValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
12609 | 23 | { |
12610 | 23 | if (tvb_reported_length_remaining(tvb, offset) <= 0) |
12611 | 0 | return offset; |
12612 | 23 | offset = fRealTag(tvb, pinfo, tree, offset, "limit: "); |
12613 | 23 | if (tvb_reported_length_remaining(tvb, offset) <= 0) |
12614 | 1 | return offset; |
12615 | 22 | offset = fBitStringTag(tvb, pinfo, tree, offset, "values: "); |
12616 | 22 | if (tvb_reported_length_remaining(tvb, offset) <= 0) |
12617 | 1 | return offset; |
12618 | 21 | offset = fRealTag(tvb, pinfo, tree, offset, "deadband: "); |
12619 | 21 | return offset; |
12620 | 22 | } |
12621 | | |
12622 | | static unsigned |
12623 | | fLifeSafetyInfo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
12624 | 0 | { |
12625 | 0 | unsigned lastoffset = 0; |
12626 | 0 | uint8_t tag_no, tag_info; |
12627 | 0 | uint32_t lvt; |
12628 | |
|
12629 | 0 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
12630 | 0 | lastoffset = offset; |
12631 | 0 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
12632 | 0 | if (tag_is_closing(tag_info)) { |
12633 | 0 | break; |
12634 | 0 | } |
12635 | | |
12636 | 0 | switch (tag_no) { |
12637 | 0 | case 0: /* requesting-process-identifier */ |
12638 | 0 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "requesting-process-identifier: "); |
12639 | 0 | break; |
12640 | 0 | case 1: /* request */ |
12641 | 0 | offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset, |
12642 | 0 | "requested-operation: ", BACnetLifeSafetyOperation, 64); |
12643 | 0 | break; |
12644 | 0 | default: |
12645 | 0 | break; |
12646 | 0 | } |
12647 | 0 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
12648 | 0 | } |
12649 | 0 | return offset; |
12650 | 0 | } |
12651 | | |
12652 | | static unsigned |
12653 | | fAcknowledgeAlarmInfo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
12654 | 0 | { |
12655 | 0 | unsigned lastoffset = 0; |
12656 | 0 | uint8_t tag_no, tag_info; |
12657 | 0 | uint32_t lvt; |
12658 | |
|
12659 | 0 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
12660 | 0 | lastoffset = offset; |
12661 | 0 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
12662 | 0 | if (tag_is_closing(tag_info)) { |
12663 | 0 | break; |
12664 | 0 | } |
12665 | | |
12666 | 0 | switch (tag_no) { |
12667 | 0 | case 0: /* event-state-acknowledged */ |
12668 | 0 | offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset, |
12669 | 0 | "event-state-acknowledged: ", BACnetEventState, 64); |
12670 | 0 | break; |
12671 | 0 | case 1: /* timestamp */ |
12672 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); /* show context open */ |
12673 | 0 | offset = fTimeStamp(tvb, pinfo, tree, offset, "source-timestamp: "); |
12674 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); /* show context close */ |
12675 | 0 | break; |
12676 | 0 | default: |
12677 | 0 | break; |
12678 | 0 | } |
12679 | 0 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
12680 | 0 | } |
12681 | 0 | return offset; |
12682 | 0 | } |
12683 | | |
12684 | | static unsigned |
12685 | | // NOLINTNEXTLINE(misc-no-recursion) |
12686 | | fAuditNotificationInfo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
12687 | 1.68k | { |
12688 | 1.68k | unsigned len, lastoffset = 0; |
12689 | 1.68k | uint8_t tag_no, tag_info; |
12690 | 1.68k | uint32_t lvt; |
12691 | 1.68k | uint32_t operation = 0; |
12692 | 1.68k | proto_tree *subtree = tree; |
12693 | | |
12694 | 26.8k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
12695 | 26.5k | lastoffset = offset; |
12696 | 26.5k | len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
12697 | 26.5k | if (tag_is_closing(tag_info)) { |
12698 | 312 | break; |
12699 | 312 | } |
12700 | | |
12701 | 26.2k | switch (tag_no) { |
12702 | 7.55k | case 0: /* source-timestamp */ |
12703 | 7.55k | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); /* show context open */ |
12704 | 7.55k | offset = fTimeStamp(tvb, pinfo, tree, offset, "source-timestamp: "); |
12705 | 7.55k | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); /* show context close */ |
12706 | 7.55k | break; |
12707 | 1.37k | case 1: /* target-timestamp */ |
12708 | 1.37k | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); /* show context open */ |
12709 | 1.37k | offset = fTimeStamp(tvb, pinfo, tree, offset, "target-timestamp: "); |
12710 | 1.37k | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); /* show context close */ |
12711 | 1.37k | break; |
12712 | 1.62k | case 2: /* source-device */ |
12713 | 1.62k | subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_value, NULL, "source-device: "); |
12714 | 1.62k | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* show context open */ |
12715 | 1.62k | offset = fRecipient(tvb, pinfo, subtree, offset); |
12716 | 1.62k | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* show context close */ |
12717 | 1.62k | break; |
12718 | 836 | case 3: /* source-object */ |
12719 | 836 | subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_value, NULL, "source-object: "); |
12720 | 836 | offset = fObjectIdentifier(tvb, pinfo, subtree, offset, hf_bacapp_object_identifier); |
12721 | 836 | break; |
12722 | 1.94k | case 4: /* operation */ |
12723 | 1.94k | fUnsigned32(tvb, offset, lvt, &operation); |
12724 | 1.94k | offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset, |
12725 | 1.94k | "operation: ", BACnetAuditOperation, 64); |
12726 | 1.94k | break; |
12727 | 730 | case 5: /* source-comment */ |
12728 | 730 | offset = fCharacterString(tvb, pinfo, tree, offset, "source-comment: "); |
12729 | 730 | break; |
12730 | 726 | case 6: /* target-comment */ |
12731 | 726 | offset = fCharacterString(tvb, pinfo, tree, offset, "target-comment: "); |
12732 | 726 | break; |
12733 | 1.34k | case 7: /* invoke-id */ |
12734 | 1.34k | offset = fUnsignedTag(tvb, pinfo, tree, offset, "invoke-id: "); |
12735 | 1.34k | break; |
12736 | 998 | case 8: /* source-user-id */ |
12737 | 998 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "source-user-id: "); |
12738 | 998 | break; |
12739 | 769 | case 9: /* source-user-role */ |
12740 | 769 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "source-user-role: "); |
12741 | 769 | break; |
12742 | 1.40k | case 10: /* target-device */ |
12743 | 1.40k | subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_value, NULL, "target-device: "); |
12744 | 1.40k | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* show context open */ |
12745 | 1.40k | offset = fRecipient(tvb, pinfo, subtree, offset); |
12746 | 1.40k | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* show context close */ |
12747 | 1.40k | break; |
12748 | 518 | case 11: /* target-object */ |
12749 | 518 | subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_value, NULL, "target-object: "); |
12750 | 518 | offset = fObjectIdentifier(tvb, pinfo, subtree, offset, hf_bacapp_object_identifier); |
12751 | 518 | break; |
12752 | 3.11k | case 12: /* target-property */ |
12753 | 3.11k | subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_value, NULL, "target-property: "); |
12754 | 3.11k | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* show context open */ |
12755 | 3.11k | offset = fPropertyReference(tvb, pinfo, subtree, offset, 0, 0); |
12756 | 3.11k | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* show context close */ |
12757 | 3.11k | break; |
12758 | 943 | case 13: /* target-priority */ |
12759 | 943 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "target-priority: "); |
12760 | 943 | break; |
12761 | 2.17k | case 14: /* target-value */ |
12762 | 2.17k | subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_value, NULL, "target-value: "); |
12763 | 2.17k | if (operation == 4) { |
12764 | | /* operation life safety */ |
12765 | | /* inspect next tag */ |
12766 | 0 | fTagHeader(tvb, pinfo, offset + len, &tag_no, &tag_info, &lvt); |
12767 | 0 | if ( tag_no == 0 && |
12768 | 0 | ! tag_is_opening(tag_info) && |
12769 | 0 | tag_is_context_specific(tag_info) ) { |
12770 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* show context open */ |
12771 | 0 | offset = fLifeSafetyInfo(tvb, pinfo, subtree, offset); |
12772 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* show context close */ |
12773 | 0 | } else { |
12774 | | /* abstract syntax and type */ |
12775 | 0 | offset = fPropertyValue(tvb, pinfo, subtree, offset, tag_info); |
12776 | 0 | } |
12777 | 2.17k | } else if ( operation == 5 ) { |
12778 | | /* operation acknowledge alarm */ |
12779 | | /* inspect next tag */ |
12780 | 0 | fTagHeader(tvb, pinfo, offset + len, &tag_no, &tag_info, &lvt); |
12781 | 0 | if ( tag_no == 0 && |
12782 | 0 | ! tag_is_opening(tag_info) && |
12783 | 0 | tag_is_context_specific(tag_info) ) { |
12784 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* show context open */ |
12785 | 0 | offset = fAcknowledgeAlarmInfo(tvb, pinfo, subtree, offset); |
12786 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* show context close */ |
12787 | 0 | } else { |
12788 | | /* abstract syntax and type */ |
12789 | 0 | offset = fPropertyValue(tvb, pinfo, subtree, offset, tag_info); |
12790 | 0 | } |
12791 | 2.17k | } else { |
12792 | | /* abstract syntax and type */ |
12793 | 2.17k | offset = fPropertyValue(tvb, pinfo, subtree, offset, tag_info); |
12794 | 2.17k | } |
12795 | 2.17k | break; |
12796 | 13 | case 15: /* current-value */ |
12797 | 13 | subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_value, NULL, "current-value: "); |
12798 | | /* always abstract syntax and type */ |
12799 | 13 | offset = fPropertyValue(tvb, pinfo, subtree, offset, tag_info); |
12800 | 13 | break; |
12801 | 15 | case 16: /* error-result */ |
12802 | 15 | subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_value, NULL, "error-result: "); |
12803 | 15 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* show context open */ |
12804 | 15 | offset = fError(tvb, pinfo, subtree, offset); |
12805 | 15 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); /* show context close */ |
12806 | 15 | break; |
12807 | 172 | default: |
12808 | 172 | break; |
12809 | 26.2k | } |
12810 | 25.3k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
12811 | 25.3k | } |
12812 | 785 | return offset; |
12813 | 1.68k | } |
12814 | | |
12815 | | static unsigned |
12816 | | // NOLINTNEXTLINE(misc-no-recursion) |
12817 | | fAuditLogRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
12818 | 141 | { |
12819 | 141 | unsigned lastoffset = 0; |
12820 | 141 | uint8_t tag_no, tag_info; |
12821 | 141 | uint32_t lvt; |
12822 | 141 | proto_tree *subtree = tree; |
12823 | | |
12824 | 521 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
12825 | 519 | lastoffset = offset; |
12826 | 519 | fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
12827 | 519 | if (tag_is_closing(tag_info)) { |
12828 | 34 | break; |
12829 | 34 | } |
12830 | | |
12831 | 485 | switch (tag_no) { |
12832 | 311 | case 0: /* timestamp */ |
12833 | 311 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
12834 | 311 | offset = fDate(tvb, pinfo, tree, offset, "Date: "); |
12835 | 311 | offset = fTime(tvb, pinfo, tree, offset, "Time: "); |
12836 | 311 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
12837 | 311 | break; |
12838 | 111 | case 1: /* logDatum: don't loop, it's a CHOICE */ |
12839 | 111 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
12840 | 111 | switch (fTagNo(tvb, offset)) { |
12841 | 16 | case 0: /* logStatus */ /* Changed this to BitString per BACnet Spec. */ |
12842 | 16 | offset = fBitStringTagVS(tvb, pinfo, tree, offset, "log status:", BACnetLogStatus); |
12843 | 16 | break; |
12844 | 61 | case 1: /* notification */ |
12845 | 61 | subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_value, NULL, "notification: "); |
12846 | 61 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12847 | 61 | offset = fAuditNotificationInfo(tvb, pinfo, subtree, offset); |
12848 | 61 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12849 | 61 | break; |
12850 | 9 | case 2: /* time-change */ |
12851 | 9 | offset = fRealTag(tvb, pinfo, tree, offset, "time-change: "); |
12852 | 9 | break; |
12853 | 22 | default: |
12854 | 22 | return offset; |
12855 | 111 | } |
12856 | 78 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
12857 | 78 | break; |
12858 | 63 | default: |
12859 | 63 | return offset; |
12860 | 485 | } |
12861 | 380 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
12862 | 380 | } |
12863 | 36 | return offset; |
12864 | 141 | } |
12865 | | |
12866 | | static unsigned |
12867 | | // NOLINTNEXTLINE(misc-no-recursion) |
12868 | | fEventLogRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
12869 | 0 | { |
12870 | 0 | unsigned lastoffset = 0; |
12871 | 0 | uint8_t tag_no, tag_info; |
12872 | 0 | uint32_t lvt; |
12873 | 0 | proto_tree *subtree = tree; |
12874 | |
|
12875 | 0 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
12876 | 0 | lastoffset = offset; |
12877 | 0 | switch (fTagNo(tvb, offset)) { |
12878 | 0 | case 0: /* timestamp */ |
12879 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
12880 | 0 | offset = fDate(tvb, pinfo, tree, offset, "Date: "); |
12881 | 0 | offset = fTime(tvb, pinfo, tree, offset, "Time: "); |
12882 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
12883 | 0 | break; |
12884 | 0 | case 1: /* logDatum: don't loop, it's a CHOICE */ |
12885 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
12886 | 0 | switch (fTagNo(tvb, offset)) { |
12887 | 0 | case 0: /* logStatus */ /* Changed this to BitString per BACnet Spec. */ |
12888 | 0 | offset = fBitStringTagVS(tvb, pinfo, tree, offset, "log status:", BACnetLogStatus); |
12889 | 0 | break; |
12890 | 0 | case 1: /* notification */ |
12891 | 0 | subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_value, NULL, "notification: "); |
12892 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12893 | 0 | offset = fConfirmedEventNotificationRequest(tvb, pinfo, subtree, offset); |
12894 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
12895 | 0 | break; |
12896 | 0 | case 2: /* time-change */ |
12897 | 0 | offset = fRealTag(tvb, pinfo, tree, offset, "time-change: "); |
12898 | 0 | break; |
12899 | 0 | default: |
12900 | 0 | return offset; |
12901 | 0 | } |
12902 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
12903 | 0 | break; |
12904 | 0 | default: |
12905 | 0 | return offset; |
12906 | 0 | } |
12907 | 0 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
12908 | 0 | } |
12909 | 0 | return offset; |
12910 | 0 | } |
12911 | | |
12912 | | static unsigned |
12913 | | // NOLINTNEXTLINE(misc-no-recursion) |
12914 | | fLogRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
12915 | 39 | { |
12916 | 39 | unsigned lastoffset = 0; |
12917 | 39 | uint8_t tag_no, tag_info; |
12918 | 39 | uint32_t lvt; |
12919 | 39 | int32_t save_propertyIdentifier; |
12920 | | |
12921 | 198 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
12922 | 197 | lastoffset = offset; |
12923 | 197 | switch (fTagNo(tvb, offset)) { |
12924 | 79 | case 0: /* timestamp */ |
12925 | 79 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
12926 | 79 | offset = fDate(tvb, pinfo, tree, offset, "Date: "); |
12927 | 79 | offset = fTime(tvb, pinfo, tree, offset, "Time: "); |
12928 | 79 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
12929 | 79 | break; |
12930 | 54 | case 1: /* logDatum: don't loop, it's a CHOICE */ |
12931 | 54 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
12932 | 54 | switch (fTagNo(tvb, offset)) { |
12933 | 1 | case 0: /* logStatus */ /* Changed this to BitString per BACnet Spec. */ |
12934 | 1 | offset = fBitStringTagVS(tvb, pinfo, tree, offset, "log status: ", BACnetLogStatus); |
12935 | 1 | break; |
12936 | 38 | case 1: |
12937 | 38 | offset = fBooleanTag(tvb, pinfo, tree, offset, "boolean-value: "); |
12938 | 38 | break; |
12939 | 3 | case 2: |
12940 | 3 | offset = fRealTag(tvb, pinfo, tree, offset, "real value: "); |
12941 | 3 | break; |
12942 | 1 | case 3: |
12943 | 1 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "enum value: "); |
12944 | 1 | break; |
12945 | 0 | case 4: |
12946 | 0 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "unsigned value: "); |
12947 | 0 | break; |
12948 | 6 | case 5: |
12949 | 6 | offset = fSignedTag(tvb, pinfo, tree, offset, "signed value: "); |
12950 | 6 | break; |
12951 | 1 | case 6: |
12952 | 1 | offset = fBitStringTag(tvb, pinfo, tree, offset, "bitstring value: "); |
12953 | 1 | break; |
12954 | 1 | case 7: |
12955 | 1 | offset = fNullTag(tvb, pinfo, tree, offset, "null value: "); |
12956 | 1 | break; |
12957 | 2 | case 8: |
12958 | 2 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
12959 | 2 | offset = fError(tvb, pinfo, tree, offset); |
12960 | 2 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
12961 | 2 | break; |
12962 | 0 | case 9: |
12963 | 0 | offset = fRealTag(tvb, pinfo, tree, offset, "time change: "); |
12964 | 0 | break; |
12965 | 0 | case 10: /* any Value */ |
12966 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
12967 | | /* this ASN-1 construction may contain also an property identifier, so |
12968 | | save the one we have got and restore it later and invalidate current |
12969 | | one to avoid misinterpretations */ |
12970 | 0 | save_propertyIdentifier = propertyIdentifier; |
12971 | 0 | propertyIdentifier = -1; |
12972 | 0 | offset = fAbstractSyntaxNType(tvb, pinfo, tree, offset); |
12973 | 0 | propertyIdentifier = save_propertyIdentifier; |
12974 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
12975 | 0 | break; |
12976 | 1 | default: |
12977 | 1 | return offset; |
12978 | 54 | } |
12979 | 52 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
12980 | 52 | break; |
12981 | 29 | case 2: |
12982 | | /* Changed this to BitString per BACnet Spec. */ |
12983 | 29 | offset = fBitStringTagVS(tvb, pinfo, tree, offset, "Status Flags: ", BACnetStatusFlags); |
12984 | 29 | break; |
12985 | 35 | default: |
12986 | 35 | return offset; |
12987 | 197 | } |
12988 | 159 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
12989 | 159 | } |
12990 | 1 | return offset; |
12991 | 39 | } |
12992 | | |
12993 | | static unsigned |
12994 | | // NOLINTNEXTLINE(misc-no-recursion) |
12995 | | fLogMultipleRecord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
12996 | 0 | { |
12997 | 0 | unsigned lastoffset = 0; |
12998 | 0 | uint8_t tag_no, tag_info; |
12999 | 0 | uint32_t lvt; |
13000 | 0 | int32_t save_propertyIdentifier; |
13001 | |
|
13002 | 0 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
13003 | 0 | lastoffset = offset; |
13004 | 0 | switch (fTagNo(tvb, offset)) { |
13005 | 0 | case 0: /* timestamp */ |
13006 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13007 | 0 | offset = fDate(tvb, pinfo, tree, offset, "Date: "); |
13008 | 0 | offset = fTime(tvb, pinfo, tree, offset, "Time: "); |
13009 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13010 | 0 | break; |
13011 | 0 | case 1: /* logData: don't loop, it's a CHOICE */ |
13012 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13013 | 0 | switch (fTagNo(tvb, offset)) { |
13014 | 0 | case 0: /* logStatus */ /* Changed this to BitString per BACnet Spec. */ |
13015 | 0 | offset = fBitStringTagVS(tvb, pinfo, tree, offset, "log status: ", BACnetLogStatus); |
13016 | 0 | break; |
13017 | 0 | case 1: /* log-data: SEQUENCE OF CHOICE */ |
13018 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13019 | 0 | while ((tvb_reported_length_remaining(tvb, offset) > 0) && (offset != lastoffset)) { /* exit loop if nothing happens inside */ |
13020 | 0 | lastoffset = offset; |
13021 | 0 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
13022 | 0 | if (tag_is_closing(tag_info)) { |
13023 | 0 | lastoffset = offset; |
13024 | 0 | break; |
13025 | 0 | } |
13026 | 0 | switch (tag_no) { |
13027 | 0 | case 0: |
13028 | 0 | offset = fBooleanTag(tvb, pinfo, tree, offset, "boolean-value: "); |
13029 | 0 | break; |
13030 | 0 | case 1: |
13031 | 0 | offset = fRealTag(tvb, pinfo, tree, offset, "real value: "); |
13032 | 0 | break; |
13033 | 0 | case 2: |
13034 | 0 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "enum value: "); |
13035 | 0 | break; |
13036 | 0 | case 3: |
13037 | 0 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "unsigned value: "); |
13038 | 0 | break; |
13039 | 0 | case 4: |
13040 | 0 | offset = fSignedTag(tvb, pinfo, tree, offset, "signed value: "); |
13041 | 0 | break; |
13042 | 0 | case 5: |
13043 | 0 | offset = fBitStringTag(tvb, pinfo, tree, offset, "bitstring value: "); |
13044 | 0 | break; |
13045 | 0 | case 6: |
13046 | 0 | offset = fNullTag(tvb, pinfo, tree, offset, "null value: "); |
13047 | 0 | break; |
13048 | 0 | case 7: |
13049 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13050 | 0 | offset = fError(tvb, pinfo, tree, offset); |
13051 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13052 | 0 | break; |
13053 | 0 | case 8: /* any Value */ |
13054 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13055 | | /* this ASN-1 construction may contain also an property identifier, so |
13056 | | save the one we have got and restore it later and invalidate current |
13057 | | one to avoid misinterpretations */ |
13058 | 0 | save_propertyIdentifier = propertyIdentifier; |
13059 | 0 | propertyIdentifier = -1; |
13060 | 0 | offset = fAbstractSyntaxNType(tvb, pinfo, tree, offset); |
13061 | 0 | propertyIdentifier = save_propertyIdentifier; |
13062 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13063 | 0 | break; |
13064 | 0 | default: |
13065 | 0 | return offset; |
13066 | 0 | } |
13067 | 0 | } |
13068 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13069 | 0 | break; |
13070 | 0 | case 2: |
13071 | 0 | offset = fRealTag(tvb, pinfo, tree, offset, "time-change: "); |
13072 | 0 | break; |
13073 | 0 | default: |
13074 | 0 | return offset; |
13075 | 0 | } |
13076 | 0 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13077 | 0 | break; |
13078 | 0 | default: |
13079 | 0 | return offset; |
13080 | 0 | } |
13081 | 0 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
13082 | 0 | } |
13083 | 0 | return offset; |
13084 | 0 | } |
13085 | | |
13086 | | |
13087 | | static unsigned |
13088 | | // NOLINTNEXTLINE(misc-no-recursion) |
13089 | | fConfirmedEventNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13090 | 2.47k | { |
13091 | 2.47k | unsigned lastoffset = 0; |
13092 | 2.47k | uint8_t tag_no, tag_info; |
13093 | 2.47k | uint32_t lvt; |
13094 | | |
13095 | 68.5k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
13096 | 68.1k | lastoffset = offset; |
13097 | 68.1k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
13098 | 68.1k | if (tag_is_closing(tag_info)) { |
13099 | 493 | break; |
13100 | 493 | } |
13101 | | |
13102 | 67.6k | switch (tag_no) { |
13103 | 31.1k | case 0: /* ProcessId */ |
13104 | 31.1k | offset = fProcessId(tvb, pinfo, tree, offset); |
13105 | 31.1k | break; |
13106 | 2.74k | case 1: /* initiating ObjectId */ |
13107 | 2.74k | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_object_identifier); |
13108 | 2.74k | break; |
13109 | 3.13k | case 2: /* event ObjectId */ |
13110 | 3.13k | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_object_identifier); |
13111 | 3.13k | break; |
13112 | 3.76k | case 3: /* time stamp */ |
13113 | 3.76k | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13114 | 3.76k | offset = fTimeStamp(tvb, pinfo, tree, offset, NULL); |
13115 | 3.76k | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13116 | 3.76k | break; |
13117 | 2.02k | case 4: /* notificationClass */ |
13118 | 2.02k | offset = fUnsignedTag(tvb, pinfo, tree, offset, "Notification Class: "); |
13119 | 2.02k | break; |
13120 | 2.10k | case 5: /* Priority */ |
13121 | 2.10k | offset = fUnsignedTag(tvb, pinfo, tree, offset, "Priority: "); |
13122 | 2.10k | break; |
13123 | 3.99k | case 6: /* EventType */ |
13124 | 3.99k | offset = fEventType(tvb, pinfo, tree, offset); |
13125 | 3.99k | break; |
13126 | 964 | case 7: /* messageText */ |
13127 | 964 | offset = fCharacterString(tvb, pinfo, tree, offset, "message Text: "); |
13128 | 964 | break; |
13129 | 3.56k | case 8: /* NotifyType */ |
13130 | 3.56k | offset = fNotifyType(tvb, pinfo, tree, offset); |
13131 | 3.56k | break; |
13132 | 2.09k | case 9: /* ackRequired */ |
13133 | 2.09k | offset = fBooleanTag(tvb, pinfo, tree, offset, "ack Required: "); |
13134 | 2.09k | break; |
13135 | 2.81k | case 10: /* fromState */ |
13136 | 2.81k | offset = fFromState(tvb, pinfo, tree, offset); |
13137 | 2.81k | break; |
13138 | 3.37k | case 11: /* toState */ |
13139 | 3.37k | offset = fToState(tvb, pinfo, tree, offset); |
13140 | 3.37k | break; |
13141 | 5.67k | case 12: /* NotificationParameters */ |
13142 | 5.67k | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13143 | 5.67k | offset = fNotificationParameters(tvb, pinfo, tree, offset); |
13144 | 5.67k | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13145 | 5.67k | break; |
13146 | 298 | default: |
13147 | 298 | break; |
13148 | 67.6k | } |
13149 | 66.3k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
13150 | 66.3k | } |
13151 | 1.14k | return offset; |
13152 | 2.47k | } |
13153 | | |
13154 | | static unsigned |
13155 | | fUnconfirmedEventNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13156 | 105 | { |
13157 | 105 | return fConfirmedEventNotificationRequest(tvb, pinfo, tree, offset); |
13158 | 105 | } |
13159 | | |
13160 | | static unsigned |
13161 | | fConfirmedCOVNotificationMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13162 | 98 | { |
13163 | 98 | unsigned lastoffset = 0, len; |
13164 | 98 | uint8_t tag_no, tag_info; |
13165 | 98 | uint32_t lvt; |
13166 | 98 | proto_tree *subtree = tree; |
13167 | 98 | proto_tree *subsubtree = tree; |
13168 | | |
13169 | 3.61k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
13170 | 3.59k | lastoffset = offset; |
13171 | 3.59k | len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
13172 | 3.59k | if (tag_is_closing(tag_info)) { |
13173 | 1.07k | offset += len; |
13174 | 1.07k | subtree = tree; |
13175 | 1.07k | continue; |
13176 | 1.07k | } |
13177 | | |
13178 | 2.51k | switch (tag_no) { |
13179 | 1.78k | case 0: /* ProcessId */ |
13180 | 1.78k | offset = fProcessId(tvb, pinfo, tree, offset); |
13181 | 1.78k | break; |
13182 | 180 | case 1: /* initiating DeviceId */ |
13183 | 180 | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_device_identifier); |
13184 | 180 | break; |
13185 | 210 | case 2: /* time remaining */ |
13186 | 210 | offset = fTimeSpan(tvb, pinfo, tree, offset, "Time remaining: "); |
13187 | 210 | break; |
13188 | 243 | case 3: /* timestamp */ |
13189 | 243 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13190 | 243 | offset = fDateTime(tvb, pinfo, tree, offset, "Timestamp: "); |
13191 | 243 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13192 | 243 | break; |
13193 | 59 | case 4: /* list-of-cov-notifications */ |
13194 | 59 | if (tag_is_opening(tag_info)) { |
13195 | | /* new subtree for list-of-cov-notifications */ |
13196 | 49 | subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "list-of-cov-notifications: "); |
13197 | 49 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
13198 | | |
13199 | 285 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
13200 | 285 | lastoffset = offset; |
13201 | 285 | len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
13202 | 285 | if (tag_is_closing(tag_info)) { |
13203 | | /* end for list-of-cov-notifications */ |
13204 | 37 | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
13205 | 37 | offset += len; |
13206 | 37 | subtree = tree; |
13207 | 37 | break; |
13208 | 37 | } |
13209 | | |
13210 | 248 | switch (tag_no) { |
13211 | 235 | case 0: /* monitored-object-identifier */ |
13212 | 235 | offset = fObjectIdentifier(tvb, pinfo, subtree, offset, hf_bacapp_object_identifier); |
13213 | 235 | break; |
13214 | 8 | case 1: /* list-of-values */ |
13215 | 8 | if (tag_is_opening(tag_info)) { |
13216 | | /* new subtree for list-of-values */ |
13217 | 6 | subsubtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "list-of-values: "); |
13218 | 6 | offset += fTagHeaderTree(tvb, pinfo, subsubtree, offset, &tag_no, &tag_info, &lvt); |
13219 | | |
13220 | 17 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
13221 | 17 | lastoffset = offset; |
13222 | 17 | len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
13223 | 17 | if (tag_is_closing(tag_info)) { |
13224 | | /* end of list-of-values */ |
13225 | 1 | fTagHeaderTree(tvb, pinfo, subsubtree, offset, &tag_no, &tag_info, &lvt); |
13226 | 1 | offset += len; |
13227 | 1 | break; |
13228 | 1 | } |
13229 | | |
13230 | 16 | switch (tag_no) { |
13231 | 3 | case 0: /* PropertyIdentifier */ |
13232 | 3 | offset = fPropertyIdentifier(tvb, pinfo, subsubtree, offset); |
13233 | 3 | break; |
13234 | 5 | case 1: /* propertyArrayIndex */ |
13235 | 5 | offset = fPropertyArrayIndex(tvb, pinfo, subsubtree, offset); |
13236 | 5 | break; |
13237 | 0 | case 2: /* property-value */ |
13238 | 0 | offset = fPropertyValue(tvb, pinfo, subsubtree, offset, tag_info); |
13239 | 0 | break; |
13240 | 5 | case 3: /* time-of-change */ |
13241 | 5 | offset = fTime(tvb, pinfo, subsubtree, offset, "time of change: "); |
13242 | 5 | break; |
13243 | 3 | default: |
13244 | | /* wrong tag encoding */ |
13245 | 3 | return offset; |
13246 | 16 | } |
13247 | 13 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
13248 | 13 | } |
13249 | 6 | } |
13250 | 2 | else { |
13251 | | /* wrong tag encoding */ |
13252 | 2 | expert_add_info(pinfo, subsubtree, &ei_bacapp_bad_tag); |
13253 | 2 | } |
13254 | 5 | break; |
13255 | 5 | default: |
13256 | | /* wrong tag encoding */ |
13257 | 5 | return offset; |
13258 | 248 | } |
13259 | 240 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
13260 | 240 | } |
13261 | 49 | } |
13262 | 10 | else { |
13263 | | /* wrong tag encoding */ |
13264 | 10 | expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag); |
13265 | 10 | } |
13266 | 51 | break; |
13267 | 51 | default: |
13268 | | /* wrong tag encoding */ |
13269 | 41 | return offset; |
13270 | 2.51k | } |
13271 | 2.45k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
13272 | 2.45k | } |
13273 | 35 | return offset; |
13274 | 98 | } |
13275 | | |
13276 | | static unsigned |
13277 | | fUnconfirmedCOVNotificationMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13278 | 24 | { |
13279 | 24 | return fConfirmedCOVNotificationMultipleRequest(tvb, pinfo, tree, offset); |
13280 | 24 | } |
13281 | | |
13282 | | static unsigned |
13283 | | fConfirmedCOVNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13284 | 248 | { |
13285 | 248 | unsigned lastoffset = 0, len; |
13286 | 248 | uint8_t tag_no, tag_info; |
13287 | 248 | uint32_t lvt; |
13288 | 248 | proto_tree *subtree = tree; |
13289 | | |
13290 | 4.06k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
13291 | 4.02k | lastoffset = offset; |
13292 | 4.02k | len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
13293 | 4.02k | if (tag_is_closing(tag_info)) { |
13294 | 918 | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
13295 | 918 | offset += len; |
13296 | 918 | subtree = tree; |
13297 | 918 | continue; |
13298 | 918 | } |
13299 | | |
13300 | 3.10k | switch (tag_no) { |
13301 | 1.91k | case 0: /* ProcessId */ |
13302 | 1.91k | offset = fProcessId(tvb, pinfo, tree, offset); |
13303 | 1.91k | break; |
13304 | 195 | case 1: /* initiating DeviceId */ |
13305 | 195 | offset = fObjectIdentifier(tvb, pinfo, subtree, offset, hf_bacapp_device_identifier); |
13306 | 195 | break; |
13307 | 318 | case 2: /* monitored ObjectId */ |
13308 | 318 | offset = fObjectIdentifier(tvb, pinfo, subtree, offset, hf_bacapp_object_identifier); |
13309 | 318 | break; |
13310 | 347 | case 3: /* time remaining */ |
13311 | 347 | offset = fTimeSpan(tvb, pinfo, tree, offset, "Time remaining: "); |
13312 | 347 | break; |
13313 | 225 | case 4: /* List of Values */ |
13314 | 225 | if (tag_is_opening(tag_info)) { |
13315 | 207 | subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "list of Values: "); |
13316 | 207 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
13317 | 207 | offset = fBACnetPropertyValue(tvb, pinfo, subtree, offset); |
13318 | 207 | } |
13319 | 18 | else { |
13320 | 18 | expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag); |
13321 | 18 | } |
13322 | 225 | break; |
13323 | 105 | default: |
13324 | 105 | return offset; |
13325 | 3.10k | } |
13326 | 2.91k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
13327 | 2.91k | } |
13328 | 56 | return offset; |
13329 | 248 | } |
13330 | | |
13331 | | static unsigned |
13332 | | fUnconfirmedCOVNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13333 | 9 | { |
13334 | 9 | return fConfirmedCOVNotificationRequest(tvb, pinfo, tree, offset); |
13335 | 9 | } |
13336 | | |
13337 | | static unsigned |
13338 | | fAcknowledgeAlarmRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13339 | 228 | { |
13340 | 228 | unsigned lastoffset = 0; |
13341 | 228 | uint8_t tag_no = 0, tag_info = 0; |
13342 | 228 | uint32_t lvt = 0; |
13343 | | |
13344 | 4.76k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
13345 | 4.72k | lastoffset = offset; |
13346 | 4.72k | switch (fTagNo(tvb, offset)) { |
13347 | 2.41k | case 0: /* acknowledgingProcessId */ |
13348 | 2.41k | offset = fUnsignedTag(tvb, pinfo, tree, offset, "acknowledging Process Id: "); |
13349 | 2.41k | break; |
13350 | 299 | case 1: /* eventObjectId */ |
13351 | 299 | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_object_identifier); |
13352 | 299 | break; |
13353 | 502 | case 2: /* eventStateAcknowledged */ |
13354 | 502 | offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset, |
13355 | 502 | "event State Acknowledged: ", BACnetEventState, 64); |
13356 | 502 | break; |
13357 | 812 | case 3: /* timeStamp */ |
13358 | 812 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13359 | 812 | offset = fTimeStamp(tvb, pinfo, tree, offset, NULL); |
13360 | 812 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13361 | 812 | break; |
13362 | 282 | case 4: /* acknowledgementSource */ |
13363 | 282 | offset = fCharacterString(tvb, pinfo, tree, offset, "acknowledgement Source: "); |
13364 | 282 | break; |
13365 | 268 | case 5: /* timeOfAcknowledgement */ |
13366 | 268 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13367 | 268 | offset = fTimeStamp(tvb, pinfo, tree, offset, "acknowledgement timestamp: "); |
13368 | 268 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13369 | 268 | break; |
13370 | 150 | default: |
13371 | 150 | return offset; |
13372 | 4.72k | } |
13373 | 4.54k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
13374 | 4.54k | } |
13375 | 40 | return offset; |
13376 | 228 | } |
13377 | | |
13378 | | static unsigned |
13379 | | fGetAlarmSummaryAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13380 | 40 | { |
13381 | 40 | unsigned lastoffset = 0; |
13382 | | |
13383 | 195 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
13384 | 186 | lastoffset = offset; |
13385 | 186 | offset = fApplicationTypes(tvb, pinfo, tree, offset, "Object Identifier: "); |
13386 | 186 | offset = fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, |
13387 | 186 | "alarm State: ", BACnetEventState, 64); |
13388 | 186 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, |
13389 | 186 | "acknowledged Transitions: ", BACnetEventTransitionBits); |
13390 | 186 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
13391 | 186 | } |
13392 | 40 | return offset; |
13393 | 40 | } |
13394 | | |
13395 | | static unsigned |
13396 | | fGetEnrollmentSummaryRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13397 | 108 | { |
13398 | 108 | unsigned lastoffset = 0; |
13399 | 108 | uint8_t tag_no, tag_info; |
13400 | 108 | uint32_t lvt; |
13401 | | |
13402 | 2.99k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
13403 | 2.96k | lastoffset = offset; |
13404 | 2.96k | switch (fTagNo(tvb, offset)) { |
13405 | 1.44k | case 0: /* acknowledgmentFilter */ |
13406 | 1.44k | offset = fEnumeratedTag(tvb, pinfo, tree, offset, |
13407 | 1.44k | "acknowledgment Filter: ", BACnetAcknowledgementFilter); |
13408 | 1.44k | break; |
13409 | 323 | case 1: /* eventObjectId - OPTIONAL */ |
13410 | 323 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13411 | 323 | offset = fRecipientProcess(tvb, pinfo, tree, offset); |
13412 | 323 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13413 | 323 | break; |
13414 | 454 | case 2: /* eventStateFilter */ |
13415 | 454 | offset = fEnumeratedTag(tvb, pinfo, tree, offset, |
13416 | 454 | "event State Filter: ", BACnetEventStateFilter); |
13417 | 454 | break; |
13418 | 364 | case 3: /* eventTypeFilter - OPTIONAL */ |
13419 | 364 | offset = fEnumeratedTag(tvb, pinfo, tree, offset, |
13420 | 364 | "event Type Filter: ", BACnetEventType); |
13421 | 364 | break; |
13422 | 126 | case 4: /* priorityFilter */ |
13423 | 126 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13424 | 126 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "min Priority: "); |
13425 | 126 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "max Priority: "); |
13426 | 126 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13427 | 126 | break; |
13428 | 211 | case 5: /* notificationClassFilter - OPTIONAL */ |
13429 | 211 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "notification Class Filter: "); |
13430 | 211 | break; |
13431 | 48 | default: |
13432 | 48 | return offset; |
13433 | 2.96k | } |
13434 | 2.88k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
13435 | 2.88k | } |
13436 | 25 | return offset; |
13437 | 108 | } |
13438 | | |
13439 | | static unsigned |
13440 | | fGetEnrollmentSummaryAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13441 | 43 | { |
13442 | 43 | unsigned lastoffset = 0; |
13443 | | |
13444 | 400 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
13445 | 380 | lastoffset = offset; |
13446 | 380 | offset = fApplicationTypes(tvb, pinfo, tree, offset, "Object Identifier: "); |
13447 | 380 | offset = fApplicationTypesEnumeratedSplit(tvb, pinfo, tree, offset, |
13448 | 380 | "event Type: ", BACnetEventType, 64); |
13449 | 380 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, |
13450 | 380 | "event State: ", BACnetEventState); |
13451 | 380 | offset = fApplicationTypes(tvb, pinfo, tree, offset, "Priority: "); |
13452 | 380 | if (tvb_reported_length_remaining(tvb, offset) > 0 && fTagNo(tvb, offset) == 2) /* Notification Class - OPTIONAL */ |
13453 | 42 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "Notification Class: "); |
13454 | 380 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
13455 | 380 | } |
13456 | | |
13457 | 43 | return offset; |
13458 | 43 | } |
13459 | | |
13460 | | static unsigned |
13461 | | fGetEventInformationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13462 | 37 | { |
13463 | 37 | if (tvb_reported_length_remaining(tvb, offset) > 0) { |
13464 | 37 | if (fTagNo(tvb, offset) == 0) { |
13465 | 35 | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_object_identifier); |
13466 | 35 | } |
13467 | 37 | } |
13468 | 37 | return offset; |
13469 | 37 | } |
13470 | | |
13471 | | static unsigned |
13472 | | flistOfEventSummaries(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13473 | 186 | { |
13474 | 186 | unsigned lastoffset = 0; |
13475 | 186 | uint8_t tag_no, tag_info; |
13476 | 186 | uint32_t lvt; |
13477 | 186 | proto_tree* subtree = tree; |
13478 | | |
13479 | 2.11k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
13480 | 2.10k | lastoffset = offset; |
13481 | 2.10k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
13482 | | /* we are finished here if we spot a closing tag */ |
13483 | 2.10k | if (tag_is_closing(tag_info)) { |
13484 | 57 | break; |
13485 | 57 | } |
13486 | 2.05k | switch (tag_no) { |
13487 | 649 | case 0: /* ObjectId */ |
13488 | 649 | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_object_identifier); |
13489 | 649 | break; |
13490 | 208 | case 1: /* eventState */ |
13491 | 208 | offset = fEnumeratedTag(tvb, pinfo, tree, offset, |
13492 | 208 | "event State: ", BACnetEventState); |
13493 | 208 | break; |
13494 | 108 | case 2: /* acknowledgedTransitions */ |
13495 | 108 | offset = fBitStringTagVS(tvb, pinfo, tree, offset, |
13496 | 108 | "acknowledged Transitions: ", BACnetEventTransitionBits); |
13497 | 108 | break; |
13498 | 247 | case 3: /* eventTimeStamps */ |
13499 | 247 | subtree = proto_tree_add_subtree(tree, tvb, offset, lvt, ett_bacapp_tag, NULL, "eventTimeStamps"); |
13500 | 247 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
13501 | 247 | offset = fTimeStamp(tvb, pinfo, subtree, offset, "TO-OFFNORMAL timestamp: "); |
13502 | 247 | offset = fTimeStamp(tvb, pinfo, subtree, offset, "TO-FAULT timestamp: "); |
13503 | 247 | offset = fTimeStamp(tvb, pinfo, subtree, offset, "TO-NORMAL timestamp: "); |
13504 | 247 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
13505 | 247 | break; |
13506 | 465 | case 4: /* notifyType */ |
13507 | 465 | offset = fNotifyType(tvb, pinfo, tree, offset); |
13508 | 465 | break; |
13509 | 183 | case 5: /* eventEnable */ |
13510 | 183 | offset = fBitStringTagVS(tvb, pinfo, tree, offset, |
13511 | 183 | "event Enable: ", BACnetEventTransitionBits); |
13512 | 183 | break; |
13513 | 97 | case 6: /* eventPriorities */ |
13514 | 97 | subtree = proto_tree_add_subtree(tree, tvb, offset, lvt, ett_bacapp_tag, NULL, "eventPriorities"); |
13515 | 97 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
13516 | 97 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "TO-OFFNORMAL Priority: "); |
13517 | 97 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "TO-FAULT Priority: "); |
13518 | 97 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "TO-NORMAL Priority: "); |
13519 | 97 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
13520 | 97 | break; |
13521 | 95 | default: |
13522 | 95 | return offset; |
13523 | 2.05k | } |
13524 | 1.93k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
13525 | 1.93k | } |
13526 | 67 | return offset; |
13527 | 186 | } |
13528 | | |
13529 | | static unsigned |
13530 | | fLOPR(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13531 | 91 | { |
13532 | 91 | unsigned lastoffset = 0; |
13533 | 91 | uint8_t tag_no, tag_info; |
13534 | 91 | uint32_t lvt; |
13535 | | |
13536 | 91 | col_set_writable(pinfo->cinfo, COL_INFO, false); /* don't set all infos into INFO column */ |
13537 | 113 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
13538 | 111 | lastoffset = offset; |
13539 | 111 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
13540 | | /* we are finished here if we spot a closing tag */ |
13541 | 111 | if (tag_is_closing(tag_info)) { |
13542 | 2 | break; |
13543 | 2 | } |
13544 | 109 | offset = fDeviceObjectPropertyReference(tvb, pinfo, tree, offset); |
13545 | 109 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
13546 | 109 | } |
13547 | 91 | return offset; |
13548 | 91 | } |
13549 | | |
13550 | | static unsigned |
13551 | | fGetEventInformationACK(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13552 | 76 | { |
13553 | 76 | unsigned lastoffset = 0; |
13554 | 76 | uint8_t tag_no, tag_info; |
13555 | 76 | uint32_t lvt; |
13556 | | |
13557 | 382 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
13558 | 378 | lastoffset = offset; |
13559 | 378 | switch (fTagNo(tvb, offset)) { |
13560 | 186 | case 0: /* listOfEventSummaries */ |
13561 | 186 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13562 | 186 | offset = flistOfEventSummaries(tvb, pinfo, tree, offset); |
13563 | 186 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13564 | 186 | break; |
13565 | 154 | case 1: /* moreEvents */ |
13566 | 154 | offset = fBooleanTag(tvb, pinfo, tree, offset, "more Events: "); |
13567 | 154 | break; |
13568 | 38 | default: |
13569 | 38 | return offset; |
13570 | 378 | } |
13571 | 306 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
13572 | 306 | } |
13573 | 4 | return offset; |
13574 | 76 | } |
13575 | | |
13576 | | static unsigned |
13577 | | fAddListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13578 | 1.23k | { |
13579 | 1.23k | unsigned lastoffset = 0, len; |
13580 | 1.23k | uint8_t tag_no, tag_info; |
13581 | 1.23k | uint32_t lvt; |
13582 | 1.23k | proto_tree *subtree = tree; |
13583 | | |
13584 | 1.23k | col_set_writable(pinfo->cinfo, COL_INFO, false); /* don't set all infos into INFO column */ |
13585 | | |
13586 | 8.82k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
13587 | 8.81k | lastoffset = offset; |
13588 | 8.81k | len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
13589 | 8.81k | if (tag_is_closing(tag_info)) { |
13590 | 4.70k | offset += len; |
13591 | 4.70k | subtree = tree; |
13592 | 4.70k | continue; |
13593 | 4.70k | } |
13594 | | |
13595 | 4.11k | switch (tag_no) { |
13596 | 1.90k | case 0: /* ObjectId */ |
13597 | 1.90k | offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset); |
13598 | 1.90k | break; |
13599 | 1.69k | case 3: /* listOfElements */ |
13600 | 1.69k | if (tag_is_opening(tag_info)) { |
13601 | 1.64k | subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "listOfElements"); |
13602 | 1.64k | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
13603 | 1.64k | offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset); |
13604 | 1.64k | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
13605 | 1.64k | } else { |
13606 | 46 | expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag); |
13607 | 46 | } |
13608 | 1.69k | break; |
13609 | 509 | default: |
13610 | 509 | return offset; |
13611 | 4.11k | } |
13612 | 2.94k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
13613 | 2.94k | } |
13614 | 67 | return offset; |
13615 | 1.23k | } |
13616 | | |
13617 | | static unsigned |
13618 | | fDeleteObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13619 | 2 | { |
13620 | 2 | return fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_object_identifier); |
13621 | 2 | } |
13622 | | |
13623 | | static unsigned |
13624 | | fDeviceCommunicationControlRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13625 | 44 | { |
13626 | 44 | unsigned lastoffset = 0; |
13627 | | |
13628 | 692 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
13629 | 685 | lastoffset = offset; |
13630 | | |
13631 | 685 | switch (fTagNo(tvb, offset)) { |
13632 | 361 | case 0: /* timeDuration */ |
13633 | 361 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "time Duration: "); |
13634 | 361 | break; |
13635 | 218 | case 1: /* enable-disable */ |
13636 | 218 | offset = fEnumeratedTag(tvb, pinfo, tree, offset, "enable-disable: ", |
13637 | 218 | BACnetEnableDisable); |
13638 | 218 | break; |
13639 | 78 | case 2: /* password - OPTIONAL */ |
13640 | 78 | offset = fCharacterString(tvb, pinfo, tree, offset, "Password: "); |
13641 | 78 | break; |
13642 | 28 | default: |
13643 | 28 | return offset; |
13644 | 685 | } |
13645 | 648 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
13646 | 648 | } |
13647 | 7 | return offset; |
13648 | 44 | } |
13649 | | |
13650 | | static unsigned |
13651 | | fReinitializeDeviceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13652 | 31 | { |
13653 | 31 | unsigned lastoffset = 0; |
13654 | | |
13655 | 627 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
13656 | 622 | lastoffset = offset; |
13657 | | |
13658 | 622 | switch (fTagNo(tvb, offset)) { |
13659 | 420 | case 0: /* reinitializedStateOfDevice */ |
13660 | 420 | offset = fEnumeratedTag(tvb, pinfo, tree, offset, |
13661 | 420 | "reinitialized State Of Device: ", |
13662 | 420 | BACnetReinitializedStateOfDevice); |
13663 | 420 | break; |
13664 | 177 | case 1: /* password - OPTIONAL */ |
13665 | 177 | offset = fCharacterString(tvb, pinfo, tree, offset, "Password: "); |
13666 | 177 | break; |
13667 | 25 | default: |
13668 | 25 | return offset; |
13669 | 622 | } |
13670 | 596 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
13671 | 596 | } |
13672 | 5 | return offset; |
13673 | 31 | } |
13674 | | |
13675 | | static unsigned |
13676 | | fVtOpenRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13677 | 8 | { |
13678 | 8 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, |
13679 | 8 | "vtClass: ", BACnetVTClass); |
13680 | 8 | return fApplicationTypes(tvb, pinfo, tree, offset, "local VT Session ID: "); |
13681 | 8 | } |
13682 | | |
13683 | | static unsigned |
13684 | | fVtOpenAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13685 | 2 | { |
13686 | 2 | return fApplicationTypes(tvb, pinfo, tree, offset, "remote VT Session ID: "); |
13687 | 2 | } |
13688 | | |
13689 | | static unsigned |
13690 | | fVtCloseRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13691 | 42 | { |
13692 | 42 | unsigned lastoffset = 0; |
13693 | | |
13694 | 622 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
13695 | 607 | lastoffset = offset; |
13696 | 607 | offset= fApplicationTypes(tvb, pinfo, tree, offset, "remote VT Session ID: "); |
13697 | 607 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
13698 | 607 | } |
13699 | 42 | return offset; |
13700 | 42 | } |
13701 | | |
13702 | | static unsigned |
13703 | | fVtDataRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13704 | 14 | { |
13705 | 14 | offset= fApplicationTypes(tvb, pinfo, tree, offset, "VT Session ID: "); |
13706 | 14 | offset = fApplicationTypes(tvb, pinfo, tree, offset, "VT New Data: "); |
13707 | 14 | return fApplicationTypes(tvb, pinfo, tree, offset, "VT Data Flag: "); |
13708 | 14 | } |
13709 | | |
13710 | | static unsigned |
13711 | | fVtDataAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13712 | 11 | { |
13713 | 11 | unsigned lastoffset = 0; |
13714 | | |
13715 | 188 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
13716 | 188 | lastoffset = offset; |
13717 | | |
13718 | 188 | switch (fTagNo(tvb, offset)) { |
13719 | 158 | case 0: /* BOOLEAN */ |
13720 | 158 | offset = fBooleanTag(tvb, pinfo, tree, offset, "all New Data Accepted: "); |
13721 | 158 | break; |
13722 | 19 | case 1: /* Unsigned OPTIONAL */ |
13723 | 19 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "accepted Octet Count: "); |
13724 | 19 | break; |
13725 | 11 | default: |
13726 | 11 | return offset; |
13727 | 188 | } |
13728 | 177 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
13729 | 177 | } |
13730 | 0 | return offset; |
13731 | 11 | } |
13732 | | |
13733 | | static unsigned |
13734 | | fConfirmedAuditNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13735 | 1.52k | { |
13736 | 1.52k | unsigned lastoffset = 0; |
13737 | 1.52k | unsigned firstloop = 1; |
13738 | 1.52k | uint8_t tag_no, tag_info; |
13739 | 1.52k | uint32_t lvt; |
13740 | | |
13741 | 3.07k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
13742 | 1.88k | lastoffset = offset; |
13743 | 1.88k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
13744 | 1.88k | if (tag_is_closing(tag_info)) { |
13745 | 261 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13746 | 261 | break; |
13747 | 261 | } |
13748 | | |
13749 | 1.61k | if (tag_is_opening(tag_info) && firstloop) { |
13750 | 40 | firstloop = 0; |
13751 | 40 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13752 | 40 | } |
13753 | | |
13754 | 1.61k | offset = fAuditNotificationInfo(tvb, pinfo, tree, offset); |
13755 | 1.61k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
13756 | 1.61k | } |
13757 | 1.52k | return offset; |
13758 | 1.52k | } |
13759 | | |
13760 | | static unsigned |
13761 | | fUnconfirmedAuditNotificationRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13762 | 17 | { |
13763 | 17 | return fConfirmedAuditNotificationRequest(tvb, pinfo, tree, offset); |
13764 | 17 | } |
13765 | | |
13766 | | static unsigned |
13767 | | fAuditLogQueryByTargetParameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13768 | 461 | { |
13769 | 461 | unsigned lastoffset = 0; |
13770 | 461 | uint8_t tag_no, tag_info; |
13771 | 461 | uint32_t lvt; |
13772 | | |
13773 | 4.20k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
13774 | 4.19k | lastoffset = offset; |
13775 | 4.19k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
13776 | 4.19k | if (tag_is_closing(tag_info)) { |
13777 | 122 | break; |
13778 | 122 | } |
13779 | | |
13780 | 4.07k | switch (tag_no) { |
13781 | 1.35k | case 0: /* target-device-identifier */ |
13782 | 1.35k | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_device_identifier); |
13783 | 1.35k | break; |
13784 | 405 | case 1: /* target-device-address */ |
13785 | 405 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13786 | 405 | offset = fAddress(tvb, pinfo, tree, offset); |
13787 | 405 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13788 | 405 | break; |
13789 | 351 | case 2: /* target-object-identifier */ |
13790 | 351 | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_object_identifier); |
13791 | 351 | break; |
13792 | 464 | case 3: /* target-property-identifier */ |
13793 | 464 | offset = fPropertyIdentifier(tvb, pinfo, tree, offset); |
13794 | 464 | break; |
13795 | 312 | case 4: /* target-property-array-index */ |
13796 | 312 | offset = fPropertyArrayIndex(tvb, pinfo, tree, offset); |
13797 | 312 | break; |
13798 | 362 | case 5: /* target-priority */ |
13799 | 362 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "target-priority: "); |
13800 | 362 | break; |
13801 | 251 | case 6: /* target-operation */ |
13802 | 251 | offset = fBitStringTagVS(tvb, pinfo, tree, offset, |
13803 | 251 | "target-operation: ", BACnetAuditOperation); |
13804 | 251 | break; |
13805 | 388 | case 7: /* successful-action */ |
13806 | 388 | offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset, |
13807 | 388 | "target-successful-action: ", BACnetSuccessFilter, 64); |
13808 | 388 | break; |
13809 | 187 | default: |
13810 | 187 | return offset; |
13811 | 4.07k | } |
13812 | 3.83k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
13813 | 3.83k | } |
13814 | 221 | return offset; |
13815 | 461 | } |
13816 | | |
13817 | | static unsigned |
13818 | | fAuditLogQueryBySourceParameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13819 | 205 | { |
13820 | 205 | unsigned lastoffset = 0; |
13821 | 205 | uint8_t tag_no, tag_info; |
13822 | 205 | uint32_t lvt; |
13823 | | |
13824 | 1.94k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
13825 | 1.94k | lastoffset = offset; |
13826 | 1.94k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
13827 | 1.94k | if (tag_is_closing(tag_info)) { |
13828 | 55 | break; |
13829 | 55 | } |
13830 | | |
13831 | 1.88k | switch (tag_no) { |
13832 | 527 | case 0: /* source-device-identifier */ |
13833 | 527 | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_device_identifier); |
13834 | 527 | break; |
13835 | 682 | case 1: /* source-device-address */ |
13836 | 682 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13837 | 682 | offset = fAddress(tvb, pinfo, tree, offset); |
13838 | 682 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
13839 | 682 | break; |
13840 | 173 | case 2: /* source-object-identifier */ |
13841 | 173 | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_object_identifier); |
13842 | 173 | break; |
13843 | 207 | case 3: /* source-operation */ |
13844 | 207 | offset = fBitStringTagVS(tvb, pinfo, tree, offset, |
13845 | 207 | "source-operation: ", BACnetAuditOperation); |
13846 | 207 | break; |
13847 | 178 | case 4: /* successful-action */ |
13848 | 178 | offset = fEnumeratedTagSplit(tvb, pinfo, tree, offset, |
13849 | 178 | "source-successful-action: ", BACnetSuccessFilter, 64); |
13850 | 178 | break; |
13851 | 120 | default: |
13852 | 120 | return offset; |
13853 | 1.88k | } |
13854 | 1.74k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
13855 | 1.74k | } |
13856 | 60 | return offset; |
13857 | 205 | } |
13858 | | |
13859 | | static unsigned |
13860 | | fAuditLogQueryParameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13861 | 486 | { |
13862 | 486 | unsigned lastoffset = 0; |
13863 | 486 | uint8_t tag_no, tag_info; |
13864 | 486 | uint32_t lvt; |
13865 | 486 | proto_tree *subtree = tree; |
13866 | | |
13867 | 1.05k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
13868 | 1.04k | lastoffset = offset; |
13869 | 1.04k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
13870 | 1.04k | if (tag_is_closing(tag_info)) { |
13871 | 199 | break; |
13872 | 199 | } |
13873 | | |
13874 | 849 | switch (tag_no) { |
13875 | 461 | case 0: /* query-by-target-parameters */ |
13876 | 461 | subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "target-parameters: "); |
13877 | 461 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
13878 | 461 | offset = fAuditLogQueryByTargetParameters(tvb, pinfo, subtree, offset); |
13879 | 461 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
13880 | 461 | break; |
13881 | 205 | case 1: /* query-by-source-parameters */ |
13882 | 205 | subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "source-parameters: "); |
13883 | 205 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
13884 | 205 | offset = fAuditLogQueryBySourceParameters(tvb, pinfo, subtree, offset); |
13885 | 205 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
13886 | 205 | break; |
13887 | 183 | default: |
13888 | 183 | return offset; |
13889 | 849 | } |
13890 | 570 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
13891 | 570 | } |
13892 | 207 | return offset; |
13893 | 486 | } |
13894 | | |
13895 | | static unsigned |
13896 | | fAuditLogQueryRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13897 | 231 | { |
13898 | 231 | unsigned lastoffset = 0; |
13899 | 231 | uint8_t tag_no, tag_info; |
13900 | 231 | uint32_t lvt; |
13901 | 231 | proto_tree *subtree = tree; |
13902 | | |
13903 | 2.86k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
13904 | 2.84k | lastoffset = offset; |
13905 | 2.84k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
13906 | | |
13907 | 2.84k | switch (tag_no) { |
13908 | 730 | case 0: /* audit-log */ |
13909 | 730 | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_object_identifier); |
13910 | 730 | break; |
13911 | 486 | case 1: /* query-parameters */ |
13912 | 486 | subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "query-parameters: "); |
13913 | 486 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
13914 | 486 | offset = fAuditLogQueryParameters(tvb, pinfo, subtree, offset); |
13915 | 486 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
13916 | 486 | break; |
13917 | 779 | case 2: /* start-at-sequence-number */ |
13918 | 779 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "start-at-sequence-number: "); |
13919 | 779 | break; |
13920 | 762 | case 3: /* requested-count */ |
13921 | 762 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "requested-count: "); |
13922 | 762 | break; |
13923 | 80 | default: |
13924 | 80 | return offset; |
13925 | 2.84k | } |
13926 | 2.63k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
13927 | 2.63k | } |
13928 | 19 | return offset; |
13929 | 231 | } |
13930 | | |
13931 | | static unsigned |
13932 | | fAuditLogRecordResult(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13933 | 230 | { |
13934 | 230 | unsigned lastoffset = 0; |
13935 | 230 | uint8_t tag_no, tag_info; |
13936 | 230 | uint32_t lvt; |
13937 | 230 | proto_tree *subtree = tree; |
13938 | | |
13939 | 983 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
13940 | 981 | lastoffset = offset; |
13941 | 981 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
13942 | 981 | if (tag_is_closing(tag_info)) { |
13943 | 117 | break; |
13944 | 117 | } |
13945 | | |
13946 | 864 | switch (tag_no) { |
13947 | 634 | case 0 : /* sequence-number */ |
13948 | 634 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "sequence-number: "); |
13949 | 634 | break; |
13950 | 141 | case 1: /* log-record */ |
13951 | 141 | subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_value, NULL, "log-record: "); |
13952 | 141 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
13953 | 141 | offset = fAuditLogRecord(tvb, pinfo, subtree, offset); |
13954 | 141 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
13955 | 141 | break; |
13956 | 89 | default: |
13957 | 89 | return offset; |
13958 | 864 | } |
13959 | 753 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
13960 | 753 | } |
13961 | 119 | return offset; |
13962 | 230 | } |
13963 | | |
13964 | | static unsigned |
13965 | | fAuditLogQueryAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
13966 | 69 | { |
13967 | 69 | unsigned lastoffset = 0; |
13968 | 69 | uint8_t tag_no, tag_info; |
13969 | 69 | uint32_t lvt; |
13970 | 69 | proto_tree *subtree = tree; |
13971 | | |
13972 | 1.20k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
13973 | 1.20k | lastoffset = offset; |
13974 | 1.20k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
13975 | | |
13976 | 1.20k | switch (tag_no) { |
13977 | 257 | case 0: /* audit-log */ |
13978 | 257 | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_object_identifier); |
13979 | 257 | break; |
13980 | 230 | case 1: /* records */ |
13981 | 230 | subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "records: "); |
13982 | 230 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
13983 | 230 | offset = fAuditLogRecordResult(tvb, pinfo, subtree, offset); |
13984 | 230 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
13985 | 230 | break; |
13986 | 684 | case 2: /* no-more-items */ |
13987 | 684 | offset = fBooleanTag(tvb, pinfo, tree, offset, "no-more-items: "); |
13988 | 684 | break; |
13989 | 32 | default: |
13990 | 32 | return offset; |
13991 | 1.20k | } |
13992 | 1.14k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
13993 | 1.14k | } |
13994 | 5 | return offset; |
13995 | 69 | } |
13996 | | |
13997 | | static unsigned |
13998 | | fAuthRequestTokenRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, const char *lable) |
13999 | 334 | { |
14000 | 334 | unsigned lastoffset = 0; |
14001 | 334 | uint8_t tag_no, tag_info; |
14002 | 334 | uint32_t lvt; |
14003 | 334 | proto_tree *subtree = tree; |
14004 | 334 | proto_tree *subsubtree = tree; |
14005 | | |
14006 | 334 | subtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0, |
14007 | 334 | ett_bacapp_value, NULL, "%s", lable); |
14008 | | |
14009 | 1.79k | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
14010 | 1.78k | lastoffset = offset; |
14011 | | /* check the tag. A closing tag means we are done */ |
14012 | 1.78k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
14013 | 1.78k | if (tag_is_closing(tag_info)) { |
14014 | 156 | return offset; |
14015 | 156 | } |
14016 | | |
14017 | 1.63k | switch (tag_no) { |
14018 | 1.34k | case 0: /* client */ |
14019 | 1.34k | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "client: "); |
14020 | 1.34k | break; |
14021 | 79 | case 1: /* audience */ |
14022 | 79 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
14023 | 79 | subsubtree = proto_tree_add_subtree_format(subtree, tvb, offset, 0, |
14024 | 79 | ett_bacapp_value, NULL, "%s", "audience:"); |
14025 | | |
14026 | 3.24k | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
14027 | 3.22k | lastoffset = offset; |
14028 | | /* check the tag. A closing tag means we are done */ |
14029 | 3.22k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
14030 | 3.22k | if (tag_is_closing(tag_info)) { |
14031 | 59 | break; |
14032 | 59 | } |
14033 | | |
14034 | 3.16k | offset = fSignedTag(tvb, pinfo, subsubtree, offset, "listener: "); |
14035 | 3.16k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
14036 | 3.16k | } |
14037 | 79 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
14038 | 79 | break; |
14039 | 76 | case 2: /* scope */ |
14040 | 76 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
14041 | 76 | offset = fAuthorizationScope(tvb, pinfo, subtree, offset, "scope: "); |
14042 | 76 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
14043 | 76 | break; |
14044 | 135 | default: |
14045 | 135 | return offset; |
14046 | 1.63k | } |
14047 | 1.63k | } |
14048 | | |
14049 | 7 | return offset; |
14050 | 334 | } |
14051 | | |
14052 | | static unsigned |
14053 | | fAuthRequestRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
14054 | 79 | { |
14055 | 79 | unsigned lastoffset = 0; |
14056 | 79 | uint8_t tag_no, tag_info; |
14057 | 79 | uint32_t lvt; |
14058 | 79 | proto_tree *subtree = tree; |
14059 | | |
14060 | 370 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
14061 | 367 | lastoffset = offset; |
14062 | 367 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
14063 | | |
14064 | 367 | switch (tag_no) { |
14065 | 334 | case 0: /* token */ |
14066 | 334 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
14067 | 334 | offset = fAuthRequestTokenRequest(tvb, pinfo, subtree, offset, "token: "); |
14068 | 334 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
14069 | 334 | break; |
14070 | 32 | default: |
14071 | 32 | return offset; |
14072 | 367 | } |
14073 | 291 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
14074 | 291 | } |
14075 | 3 | return offset; |
14076 | 79 | } |
14077 | | |
14078 | | static unsigned |
14079 | | fAuthRequestAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
14080 | 139 | { |
14081 | 139 | unsigned lastoffset = 0; |
14082 | 139 | uint8_t tag_no, tag_info; |
14083 | 139 | uint32_t lvt; |
14084 | 139 | proto_tree *subtree = tree; |
14085 | | |
14086 | 417 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
14087 | 414 | lastoffset = offset; |
14088 | 414 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
14089 | | |
14090 | 414 | switch (tag_no) { |
14091 | 369 | case 0: /* token */ |
14092 | 369 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
14093 | 369 | offset = fAccessToken(tvb, pinfo, subtree, offset, "token: "); |
14094 | 369 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
14095 | 369 | break; |
14096 | 44 | default: |
14097 | 44 | return offset; |
14098 | 414 | } |
14099 | 278 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
14100 | 278 | } |
14101 | 3 | return offset; |
14102 | 139 | } |
14103 | | |
14104 | | static unsigned |
14105 | | fAuthRequestError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
14106 | 16 | { |
14107 | 16 | unsigned lastoffset = 0; |
14108 | 16 | uint8_t tag_no, tag_info; |
14109 | 16 | uint32_t lvt; |
14110 | 16 | proto_tree *subtree = tree; |
14111 | | |
14112 | 128 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
14113 | 127 | lastoffset = offset; |
14114 | 127 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
14115 | | |
14116 | 127 | switch (tag_no) { |
14117 | 93 | case 0: /* error */ |
14118 | 93 | offset = fContextTaggedError(tvb, pinfo, subtree, offset); |
14119 | 93 | break; |
14120 | 24 | case 1: /* details */ |
14121 | 24 | offset = fCharacterString(tvb, pinfo, subtree, offset, "details: "); |
14122 | 24 | break; |
14123 | 10 | default: |
14124 | 10 | return offset; |
14125 | 127 | } |
14126 | 112 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
14127 | 112 | } |
14128 | 1 | return offset; |
14129 | 16 | } |
14130 | | |
14131 | | static unsigned |
14132 | | fWhoAmIRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
14133 | 14 | { |
14134 | 14 | unsigned lastoffset = 0; |
14135 | | |
14136 | 107 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
14137 | 105 | lastoffset = offset; |
14138 | 105 | offset = fApplicationTypes(tvb, pinfo, tree, offset, "Vendor ID: "); |
14139 | 105 | offset = fApplicationTypes(tvb, pinfo, tree, offset, "Model name: "); |
14140 | 105 | offset = fApplicationTypes(tvb, pinfo, tree, offset, "Serial number: "); |
14141 | 105 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
14142 | 105 | } |
14143 | 14 | return offset; |
14144 | 14 | } |
14145 | | |
14146 | | static unsigned |
14147 | | fYouAreRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
14148 | 21 | { |
14149 | 21 | unsigned lastoffset = 0; |
14150 | 21 | uint8_t tag_no, tag_info; |
14151 | 21 | uint32_t lvt; |
14152 | | |
14153 | 180 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
14154 | 174 | lastoffset = offset; |
14155 | 174 | offset = fApplicationTypes(tvb, pinfo, tree, offset, "Vendor ID: "); |
14156 | 174 | offset = fApplicationTypes(tvb, pinfo, tree, offset, "Model name: "); |
14157 | 174 | offset = fApplicationTypes(tvb, pinfo, tree, offset, "Serial number: "); |
14158 | | |
14159 | 174 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
14160 | 174 | if(tvb_reported_length_remaining(tvb, offset) > 0 && tag_no == 12) { |
14161 | 17 | offset = fApplicationTypes(tvb, pinfo, tree, offset, "Device Identifier: "); |
14162 | 17 | } |
14163 | | |
14164 | 174 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
14165 | 174 | if(tvb_reported_length_remaining(tvb, offset) > 0 && tag_no == 6) { |
14166 | 17 | offset = fApplicationTypes(tvb, pinfo, tree, offset, "Device MAC address: "); |
14167 | 17 | } |
14168 | 174 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
14169 | 174 | } |
14170 | 21 | return offset; |
14171 | 21 | } |
14172 | | |
14173 | | static unsigned |
14174 | | fAuthenticateRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
14175 | 58 | { |
14176 | 58 | unsigned lastoffset = 0; |
14177 | | |
14178 | 1.76k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
14179 | 1.75k | lastoffset = offset; |
14180 | | |
14181 | 1.75k | switch (fTagNo(tvb, offset)) { |
14182 | 680 | case 0: /* Unsigned32 */ |
14183 | 680 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "pseudo Random Number: "); |
14184 | 680 | break; |
14185 | 448 | case 1: /* expected Invoke ID Unsigned8 OPTIONAL */ |
14186 | 448 | proto_tree_add_item(tree, hf_bacapp_invoke_id, tvb, offset++, 1, ENC_BIG_ENDIAN); |
14187 | 448 | break; |
14188 | 140 | case 2: /* Character String OPTIONAL */ |
14189 | 140 | offset = fCharacterString(tvb, pinfo, tree, offset, "operator Name: "); |
14190 | 140 | break; |
14191 | 201 | case 3: /* Character String OPTIONAL */ |
14192 | 201 | offset = fCharacterString(tvb, pinfo, tree, offset, "operator Password: "); |
14193 | 201 | break; |
14194 | 247 | case 4: /* Boolean OPTIONAL */ |
14195 | 247 | offset = fBooleanTag(tvb, pinfo, tree, offset, "start Encyphered Session: "); |
14196 | 247 | break; |
14197 | 43 | default: |
14198 | 43 | return offset; |
14199 | 1.75k | } |
14200 | 1.70k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
14201 | 1.70k | } |
14202 | 8 | return offset; |
14203 | 58 | } |
14204 | | |
14205 | | static unsigned |
14206 | | fAuthenticateAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
14207 | 2 | { |
14208 | 2 | return fApplicationTypes(tvb, pinfo, tree, offset, "modified Random Number: "); |
14209 | 2 | } |
14210 | | |
14211 | | static unsigned |
14212 | | fAuthenticationFactor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
14213 | 69 | { |
14214 | 69 | unsigned lastoffset = 0; |
14215 | 69 | uint8_t tag_no, tag_info; |
14216 | 69 | uint32_t lvt; |
14217 | | |
14218 | 938 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
14219 | 935 | lastoffset = offset; |
14220 | 935 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
14221 | | /* quit loop if we spot a closing tag */ |
14222 | 935 | if (tag_is_closing(tag_info)) { |
14223 | 15 | break; |
14224 | 15 | } |
14225 | | |
14226 | 920 | switch (tag_no) { |
14227 | 646 | case 0: /* format-type */ |
14228 | 646 | offset = fEnumeratedTag(tvb, pinfo, tree, offset, "format-type: ", NULL); |
14229 | 646 | break; |
14230 | 161 | case 1: /* format-class */ |
14231 | 161 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "format-class: "); |
14232 | 161 | break; |
14233 | 62 | case 2: /* value */ |
14234 | 62 | offset = fOctetString(tvb, pinfo, tree, offset, "value: ", lvt); |
14235 | 62 | break; |
14236 | 50 | default: |
14237 | 50 | break; |
14238 | 920 | } |
14239 | | |
14240 | 919 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
14241 | 919 | } |
14242 | | |
14243 | 68 | return offset; |
14244 | 69 | } |
14245 | | |
14246 | | static unsigned |
14247 | | fAuthenticationFactorFormat(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
14248 | 103 | { |
14249 | 103 | unsigned lastoffset = 0; |
14250 | 103 | uint8_t tag_no, tag_info; |
14251 | 103 | uint32_t lvt; |
14252 | | |
14253 | 1.20k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
14254 | 1.20k | lastoffset = offset; |
14255 | 1.20k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
14256 | | /* quit loop if we spot a closing tag */ |
14257 | 1.20k | if (tag_is_closing(tag_info)) { |
14258 | 3 | break; |
14259 | 3 | } |
14260 | | |
14261 | 1.20k | switch (tag_no) { |
14262 | 721 | case 0: /* format-type */ |
14263 | 721 | offset = fEnumeratedTag(tvb, pinfo, tree, offset, "format-type: ", NULL); |
14264 | 721 | break; |
14265 | 209 | case 1: /* vendor-id */ |
14266 | 209 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "vendor-id: "); |
14267 | 209 | break; |
14268 | 173 | case 2: /* vendor-format */ |
14269 | 173 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "vendor-format: "); |
14270 | 173 | break; |
14271 | 98 | default: |
14272 | 98 | break; |
14273 | 1.20k | } |
14274 | | |
14275 | 1.20k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
14276 | 1.20k | } |
14277 | | |
14278 | 103 | return offset; |
14279 | 103 | } |
14280 | | |
14281 | | static unsigned |
14282 | | fAuthenticationPolicy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
14283 | 241 | { |
14284 | 241 | unsigned lastoffset = 0; |
14285 | 241 | uint8_t tag_no, tag_info; |
14286 | 241 | uint32_t lvt; |
14287 | | |
14288 | 711 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
14289 | 705 | lastoffset = offset; |
14290 | 705 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
14291 | | /* quit loop if we spot a closing tag */ |
14292 | 705 | if (tag_is_closing(tag_info)) { |
14293 | 8 | break; |
14294 | 8 | } |
14295 | | |
14296 | 697 | switch (tag_no) { |
14297 | 119 | case 0: /* policy */ |
14298 | 119 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
14299 | 501 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
14300 | 497 | lastoffset = offset; |
14301 | 497 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
14302 | | /* quit loop if we spot a closing tag */ |
14303 | 497 | if (tag_is_closing(tag_info)) { |
14304 | 29 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
14305 | 29 | break; |
14306 | 29 | } |
14307 | | |
14308 | 468 | switch (tag_no) { |
14309 | 201 | case 0: /* credential-data-input */ |
14310 | 201 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
14311 | 201 | offset = fDeviceObjectReference(tvb, pinfo, tree, offset); |
14312 | 201 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
14313 | 201 | break; |
14314 | 194 | case 1: /* index */ |
14315 | 194 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "index: "); |
14316 | 194 | break; |
14317 | 73 | default: |
14318 | 73 | break; |
14319 | 468 | } |
14320 | | |
14321 | 455 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
14322 | 455 | } |
14323 | 106 | break; |
14324 | 215 | case 1: /* order-enforced */ |
14325 | 215 | offset = fBooleanTag(tvb, pinfo, tree, offset, "order-enforced: "); |
14326 | 215 | break; |
14327 | 223 | case 2: /* timeout */ |
14328 | 223 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "timeout: "); |
14329 | 223 | break; |
14330 | 140 | default: |
14331 | 140 | break; |
14332 | 697 | } |
14333 | | |
14334 | 683 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
14335 | 683 | } |
14336 | | |
14337 | 227 | return offset; |
14338 | 241 | } |
14339 | | |
14340 | | static unsigned |
14341 | | fRequestKeyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
14342 | 7 | { |
14343 | 7 | uint8_t tag_no, tag_info; |
14344 | 7 | uint32_t lvt; |
14345 | | |
14346 | 7 | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_device_identifier); /* Requesting Device Identifier */ |
14347 | 7 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
14348 | 7 | offset = fAddress(tvb, pinfo, tree, offset); |
14349 | 7 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
14350 | 7 | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_device_identifier); /* Remote Device Identifier */ |
14351 | 7 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
14352 | 7 | offset = fAddress(tvb, pinfo, tree, offset); |
14353 | 7 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
14354 | 7 | return offset; |
14355 | 7 | } |
14356 | | |
14357 | | static unsigned |
14358 | | fRemoveListElementRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
14359 | 39 | { |
14360 | | /* Same as AddListElement request after service choice */ |
14361 | 39 | return fAddListElementRequest(tvb, pinfo, tree, offset); |
14362 | 39 | } |
14363 | | |
14364 | | static unsigned |
14365 | | fReadPropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
14366 | 8 | { |
14367 | 8 | return fBACnetObjectPropertyReference(tvb, pinfo, tree, offset); |
14368 | 8 | } |
14369 | | |
14370 | | static unsigned |
14371 | | fReadPropertyAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
14372 | 39 | { |
14373 | 39 | unsigned lastoffset = 0, len; |
14374 | 39 | uint8_t tag_no, tag_info; |
14375 | 39 | uint32_t lvt; |
14376 | 39 | proto_tree *subtree = tree; |
14377 | | |
14378 | | /* set the optional global properties to indicate not-used */ |
14379 | 39 | propertyArrayIndex = -1; |
14380 | 1.15k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
14381 | 1.15k | lastoffset = offset; |
14382 | 1.15k | len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
14383 | 1.15k | if (tag_is_closing(tag_info)) { |
14384 | 563 | offset += len; |
14385 | 563 | subtree = tree; |
14386 | 563 | continue; |
14387 | 563 | } |
14388 | 588 | switch (tag_no) { |
14389 | 384 | case 0: /* objectIdentifier */ |
14390 | 384 | offset = fObjectIdentifier(tvb, pinfo, subtree, offset, hf_bacapp_object_identifier); |
14391 | 384 | break; |
14392 | 104 | case 1: /* propertyIdentifier */ |
14393 | 104 | offset = fPropertyIdentifier(tvb, pinfo, subtree, offset); |
14394 | 104 | break; |
14395 | 64 | case 2: /* propertyArrayIndex */ |
14396 | 64 | offset = fPropertyArrayIndex(tvb, pinfo, subtree, offset); |
14397 | 64 | break; |
14398 | 15 | case 3: /* propertyValue */ |
14399 | 15 | offset = fPropertyValue(tvb, pinfo, subtree, offset, tag_info); |
14400 | 15 | break; |
14401 | 20 | default: |
14402 | 20 | break; |
14403 | 588 | } |
14404 | 579 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
14405 | 579 | } |
14406 | 30 | return offset; |
14407 | 39 | } |
14408 | | |
14409 | | static unsigned |
14410 | | fWritePropertyRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
14411 | 83 | { |
14412 | 83 | unsigned lastoffset = 0; |
14413 | 83 | uint8_t tag_no, tag_info; |
14414 | 83 | uint32_t lvt; |
14415 | 83 | proto_tree *subtree = tree; |
14416 | | |
14417 | | /* set the optional global properties to indicate not-used */ |
14418 | 83 | propertyArrayIndex = -1; |
14419 | 1.59k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
14420 | 1.58k | lastoffset = offset; |
14421 | 1.58k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
14422 | | /* quit loop if we spot a closing tag */ |
14423 | 1.58k | if (tag_is_closing(tag_info)) { |
14424 | 20 | break; |
14425 | 20 | } |
14426 | | |
14427 | 1.56k | switch (tag_no) { |
14428 | 527 | case 0: /* objectIdentifier */ |
14429 | 527 | offset = fObjectIdentifier(tvb, pinfo, subtree, offset, hf_bacapp_object_identifier); |
14430 | 527 | break; |
14431 | 112 | case 1: /* propertyIdentifier */ |
14432 | 112 | offset = fPropertyIdentifier(tvb, pinfo, subtree, offset); |
14433 | 112 | break; |
14434 | 299 | case 2: /* propertyArrayIndex */ |
14435 | 299 | offset = fPropertyArrayIndex(tvb, pinfo, subtree, offset); |
14436 | 299 | break; |
14437 | 22 | case 3: /* propertyValue */ |
14438 | 22 | offset = fPropertyValue(tvb, pinfo, subtree, offset, tag_info); |
14439 | 22 | break; |
14440 | 570 | case 4: /* Priority (only used for write) */ |
14441 | 570 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "Priority: "); |
14442 | 570 | break; |
14443 | 32 | default: |
14444 | 32 | return offset; |
14445 | 1.56k | } |
14446 | 1.52k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
14447 | 1.52k | } |
14448 | 40 | return offset; |
14449 | 83 | } |
14450 | | |
14451 | | static unsigned |
14452 | | fWriteAccessSpecification(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, unsigned offset) |
14453 | 43 | { |
14454 | 43 | unsigned lastoffset = 0, len; |
14455 | 43 | uint8_t tag_no, tag_info; |
14456 | 43 | uint32_t lvt; |
14457 | | |
14458 | 768 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
14459 | 763 | lastoffset = offset; |
14460 | 763 | len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
14461 | | /* maybe a listOfwriteAccessSpecifications if we spot a closing tag */ |
14462 | 763 | if (tag_is_closing(tag_info)) { |
14463 | 502 | offset += len; |
14464 | 502 | continue; |
14465 | 502 | } |
14466 | | |
14467 | 261 | switch (tag_no) { |
14468 | 219 | case 0: /* objectIdentifier */ |
14469 | 219 | offset = fObjectIdentifier(tvb, pinfo, subtree, offset, hf_bacapp_object_identifier); |
14470 | 219 | break; |
14471 | 24 | case 1: /* listOfPropertyValues */ |
14472 | 24 | if (tag_is_opening(tag_info)) { |
14473 | 8 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
14474 | 8 | offset = fBACnetPropertyValue(tvb, pinfo, subtree, offset); |
14475 | 8 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
14476 | 16 | } else { |
14477 | 16 | expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag); |
14478 | 16 | } |
14479 | 24 | break; |
14480 | 18 | default: |
14481 | 18 | return offset; |
14482 | 261 | } |
14483 | 239 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
14484 | 239 | } |
14485 | 21 | return offset; |
14486 | 43 | } |
14487 | | |
14488 | | static unsigned |
14489 | | fWritePropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
14490 | 43 | { |
14491 | 43 | if (offset >= tvb_reported_length(tvb)) |
14492 | 0 | return offset; |
14493 | | |
14494 | 43 | col_set_writable(pinfo->cinfo, COL_INFO, false); /* don't set all infos into INFO column */ |
14495 | 43 | return fWriteAccessSpecification(tvb, pinfo, tree, offset); |
14496 | 43 | } |
14497 | | |
14498 | | static unsigned |
14499 | | fPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, uint8_t tagoffset, uint8_t list) |
14500 | 12.1k | { |
14501 | 12.1k | unsigned lastoffset = 0; |
14502 | 12.1k | uint8_t tag_no, tag_info; |
14503 | 12.1k | uint32_t lvt; |
14504 | | |
14505 | | /* set the optional global properties to indicate not-used */ |
14506 | 12.1k | propertyArrayIndex = -1; |
14507 | 18.0k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
14508 | 18.0k | lastoffset = offset; |
14509 | 18.0k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
14510 | 18.0k | if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */ |
14511 | 1.04k | return offset; |
14512 | 16.9k | } else if (tag_is_opening(tag_info)) { /* opening Tag, but not for me */ |
14513 | 2.15k | return offset; |
14514 | 2.15k | } |
14515 | 14.8k | switch (tag_no-tagoffset) { |
14516 | 6.73k | case 0: /* PropertyIdentifier */ |
14517 | 6.73k | offset = fPropertyIdentifier(tvb, pinfo, tree, offset); |
14518 | 6.73k | break; |
14519 | 1.12k | case 1: /* propertyArrayIndex */ |
14520 | 1.12k | offset = fPropertyArrayIndex(tvb, pinfo, tree, offset); |
14521 | 1.12k | if (list != 0) |
14522 | 21 | break; /* Continue decoding if this may be a list */ |
14523 | | /* FALLTHROUGH */ |
14524 | 8.05k | default: |
14525 | 8.05k | lastoffset = offset; /* Set loop end condition */ |
14526 | 8.05k | break; |
14527 | 14.8k | } |
14528 | 14.8k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
14529 | 14.8k | } |
14530 | 8.90k | return offset; |
14531 | 12.1k | } |
14532 | | |
14533 | | static unsigned |
14534 | | fBACnetPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, uint8_t list) |
14535 | 871 | { |
14536 | 871 | col_set_writable(pinfo->cinfo, COL_INFO, false); /* don't set all infos into INFO column */ |
14537 | 871 | return fPropertyReference(tvb, pinfo, tree, offset, 0, list); |
14538 | 871 | } |
14539 | | |
14540 | | static unsigned |
14541 | | fBACnetObjectPropertyReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
14542 | 2.37k | { |
14543 | 2.37k | unsigned lastoffset = 0; |
14544 | | |
14545 | 5.51k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
14546 | 5.50k | lastoffset = offset; |
14547 | | |
14548 | 5.50k | switch (fTagNo(tvb, offset)) { |
14549 | 3.16k | case 0: /* ObjectIdentifier */ |
14550 | 3.16k | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_object_identifier); |
14551 | 3.16k | break; |
14552 | 1.52k | case 1: /* PropertyIdentifier and propertyArrayIndex */ |
14553 | 1.52k | offset = fPropertyReference(tvb, pinfo, tree, offset, 1, 0); |
14554 | 1.52k | col_set_writable(pinfo->cinfo, COL_INFO, false); /* don't set all infos into INFO column */ |
14555 | | /* FALLTHROUGH */ |
14556 | 2.34k | default: |
14557 | 2.34k | lastoffset = offset; /* Set loop end condition */ |
14558 | 2.34k | break; |
14559 | 5.50k | } |
14560 | 5.47k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
14561 | 5.47k | } |
14562 | 2.34k | return offset; |
14563 | 2.37k | } |
14564 | | |
14565 | | #if 0 |
14566 | | static unsigned |
14567 | | fObjectPropertyValue(tvbuff_t *tvb, proto_tree *tree, unsigned offset) |
14568 | | { |
14569 | | unsigned lastoffset = 0; |
14570 | | uint8_t tag_no, tag_info; |
14571 | | uint32_t lvt; |
14572 | | proto_tree* subtree = tree; |
14573 | | proto_item* tt; |
14574 | | |
14575 | | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */ |
14576 | | lastoffset = offset; |
14577 | | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
14578 | | if (tag_is_closing(tag_info)) { |
14579 | | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, |
14580 | | &tag_no, &tag_info, &lvt); |
14581 | | continue; |
14582 | | } |
14583 | | switch (tag_no) { |
14584 | | case 0: /* ObjectIdentifier */ |
14585 | | offset = fObjectIdentifier(tvb, pinfo, subtree, offset, hf_bacapp_object_identifier); |
14586 | | break; |
14587 | | case 1: /* PropertyIdentifier */ |
14588 | | offset = fPropertyIdentifier(tvb, pinfo, subtree, offset); |
14589 | | break; |
14590 | | case 2: /* propertyArrayIndex */ |
14591 | | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "property Array Index: "); |
14592 | | break; |
14593 | | case 3: /* Value */ |
14594 | | offset = fPropertyValue(tvb, pinfo, subtree, offset, tag_info); |
14595 | | break; |
14596 | | case 4: /* Priority */ |
14597 | | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "Priority: "); |
14598 | | break; |
14599 | | default: |
14600 | | break; |
14601 | | } |
14602 | | } |
14603 | | return offset; |
14604 | | } |
14605 | | #endif |
14606 | | |
14607 | | static unsigned |
14608 | | // NOLINTNEXTLINE(misc-no-recursion) |
14609 | | fPriorityArray(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
14610 | 1.04k | { |
14611 | 1.04k | char i = 1, *str_ar; |
14612 | 1.04k | unsigned lastoffset = 0; |
14613 | 1.04k | uint8_t tag_no; |
14614 | 1.04k | uint8_t tag_info; |
14615 | 1.04k | uint32_t lvt; |
14616 | | |
14617 | 1.04k | if (propertyArrayIndex > 0) { |
14618 | | /* BACnetARRAY index 0 refers to the length |
14619 | | of the array, not the elements of the array. |
14620 | | BACnetARRAY index -1 is our internal flag that |
14621 | | the optional index was not used. |
14622 | | BACnetARRAY refers to this as all elements of the array. |
14623 | | If the optional index is specified for a BACnetARRAY, |
14624 | | then that specific array element is referenced. */ |
14625 | 177 | i = propertyArrayIndex; |
14626 | 177 | } |
14627 | 2.68k | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
14628 | | /* exit loop if nothing happens inside */ |
14629 | 2.33k | lastoffset = offset; |
14630 | 2.33k | str_ar = wmem_strdup_printf(pinfo->pool, "%s[%d]: ", |
14631 | 2.33k | val_to_split_str(pinfo->pool, 87 , 512, |
14632 | 2.33k | BACnetPropertyIdentifier, |
14633 | 2.33k | ASHRAE_Reserved_Fmt, |
14634 | 2.33k | Vendor_Proprietary_Fmt), |
14635 | 2.33k | i++); |
14636 | 2.33k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
14637 | 2.33k | if ( ! tag_is_context_specific(tag_info)) { |
14638 | | /* DMR Should be fAbstractNSyntax, but that's where we came from! */ |
14639 | 1.07k | offset = fApplicationTypes(tvb, pinfo, tree, offset, str_ar); |
14640 | 1.25k | } else { |
14641 | 1.25k | if (tag_is_opening(tag_info) && tag_no == 0) { |
14642 | 636 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
14643 | 636 | offset = fAbstractSyntaxNType(tvb, pinfo, tree, offset); |
14644 | 636 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
14645 | 636 | } else if (tag_is_opening(tag_info) && tag_no == 1) { |
14646 | 1 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
14647 | 1 | offset = fDate(tvb, pinfo, tree, offset, "Date: "); |
14648 | 1 | offset = fTime(tvb, pinfo, tree, offset, "Time: "); |
14649 | 1 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
14650 | 621 | } else if (tag_is_opening(tag_info) && tag_no == 2) { |
14651 | 13 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
14652 | 13 | offset = fXyColor(tvb, pinfo, tree, offset, "xy-color: "); |
14653 | 13 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
14654 | 608 | } else { |
14655 | | /* DMR Should be fAbstractNSyntax, but that's where we came from! */ |
14656 | 608 | offset = fApplicationTypes(tvb, pinfo, tree, offset, str_ar); |
14657 | 608 | } |
14658 | 1.25k | } |
14659 | | /* there are only 16 priority array elements */ |
14660 | 2.33k | if (i > 16) { |
14661 | 104 | break; |
14662 | 104 | } |
14663 | 2.23k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
14664 | 2.23k | } |
14665 | | |
14666 | 1.04k | return offset; |
14667 | 1.04k | } |
14668 | | |
14669 | | static unsigned |
14670 | | fDeviceObjectReference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
14671 | 1.42k | { |
14672 | 1.42k | uint8_t tag_no, tag_info; |
14673 | 1.42k | uint32_t lvt; |
14674 | 1.42k | unsigned lastoffset = 0; |
14675 | | |
14676 | 4.17k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
14677 | 4.15k | lastoffset = offset; |
14678 | 4.15k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
14679 | | /* quit loop if we spot an un-matched closing tag */ |
14680 | 4.15k | if (tag_is_closing(tag_info)) { |
14681 | 278 | break; |
14682 | 278 | } |
14683 | 3.87k | switch (tag_no) { |
14684 | 1.85k | case 0: /* deviceIdentifier - OPTIONAL */ |
14685 | 1.85k | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_device_identifier); |
14686 | 1.85k | break; |
14687 | 917 | case 1: /* ObjectIdentifier */ |
14688 | 917 | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_object_identifier); |
14689 | 917 | break; |
14690 | 1.10k | default: |
14691 | 1.10k | return offset; |
14692 | 3.87k | } |
14693 | 2.74k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
14694 | 2.74k | } |
14695 | 294 | return offset; |
14696 | 1.42k | } |
14697 | | |
14698 | | static unsigned |
14699 | | fSpecialEvent(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, unsigned offset) |
14700 | 101 | { |
14701 | 101 | uint8_t tag_no, tag_info; |
14702 | 101 | uint32_t lvt; |
14703 | 101 | unsigned lastoffset = 0; |
14704 | | |
14705 | 167 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
14706 | 166 | lastoffset = offset; |
14707 | 166 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
14708 | | /* quit loop if we spot an un-matched closing tag */ |
14709 | 166 | if (tag_is_closing(tag_info)) { |
14710 | 1 | break; |
14711 | 1 | } |
14712 | 165 | switch (tag_no) { |
14713 | 35 | case 0: /* calendarEntry */ |
14714 | 35 | if (tag_is_opening(tag_info)) { |
14715 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
14716 | 0 | offset = fCalendarEntry(tvb, pinfo, subtree, offset); |
14717 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
14718 | 0 | } |
14719 | 35 | break; |
14720 | 18 | case 1: /* calendarReference */ |
14721 | 18 | offset = fObjectIdentifier(tvb, pinfo, subtree, offset, hf_bacapp_object_identifier); |
14722 | 18 | break; |
14723 | 14 | case 2: /* list of BACnetTimeValue */ |
14724 | 14 | if (tag_is_opening(tag_info)) { |
14725 | 4 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
14726 | 4 | offset = fTimeValue(tvb, pinfo, subtree, offset); |
14727 | 4 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
14728 | 10 | } else { |
14729 | 10 | expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag); |
14730 | 10 | } |
14731 | 14 | break; |
14732 | 45 | case 3: /* eventPriority */ |
14733 | 45 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "event priority: "); |
14734 | 45 | break; |
14735 | 53 | default: |
14736 | 53 | return offset; |
14737 | 165 | } |
14738 | 111 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
14739 | 111 | } |
14740 | 47 | return offset; |
14741 | 101 | } |
14742 | | |
14743 | | static unsigned |
14744 | | fNetworkSecurityPolicy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
14745 | 0 | { |
14746 | 0 | unsigned lastoffset = 0; |
14747 | 0 | uint8_t tag_no, tag_info; |
14748 | 0 | uint32_t lvt; |
14749 | 0 | proto_tree *subtree; |
14750 | |
|
14751 | 0 | subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_tag, NULL, "network security policy"); |
14752 | |
|
14753 | 0 | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
14754 | 0 | lastoffset = offset; |
14755 | | /* check the tag. A closing tag means we are done */ |
14756 | 0 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
14757 | 0 | if (tag_is_closing(tag_info)) { |
14758 | 0 | return offset; |
14759 | 0 | } |
14760 | 0 | switch (tag_no) { |
14761 | 0 | case 0: /* port-id */ |
14762 | 0 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "port-id: "); |
14763 | 0 | break; |
14764 | 0 | case 1: /* security-level */ |
14765 | 0 | offset = fEnumeratedTag(tvb, pinfo, subtree, offset, |
14766 | 0 | "security-level: ", BACnetSecurityPolicy); |
14767 | 0 | break; |
14768 | 0 | default: |
14769 | 0 | return offset; |
14770 | 0 | } |
14771 | 0 | } |
14772 | | |
14773 | 0 | return offset; |
14774 | 0 | } |
14775 | | |
14776 | | static unsigned |
14777 | | fKeyIdentifier(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
14778 | 0 | { |
14779 | 0 | unsigned lastoffset = 0; |
14780 | 0 | uint8_t tag_no, tag_info; |
14781 | 0 | uint32_t lvt; |
14782 | |
|
14783 | 0 | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
14784 | 0 | lastoffset = offset; |
14785 | | /* check the tag. A closing tag means we are done */ |
14786 | 0 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
14787 | 0 | if (tag_is_closing(tag_info)) { |
14788 | 0 | return offset; |
14789 | 0 | } |
14790 | 0 | switch (tag_no) { |
14791 | 0 | case 0: /* algorithm */ |
14792 | 0 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "algorithm: "); |
14793 | 0 | break; |
14794 | 0 | case 1: /* key-id */ |
14795 | 0 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "key-id: "); |
14796 | 0 | break; |
14797 | 0 | default: |
14798 | 0 | return offset; |
14799 | 0 | } |
14800 | 0 | } |
14801 | | |
14802 | 0 | return offset; |
14803 | 0 | } |
14804 | | |
14805 | | static unsigned |
14806 | | fSecurityKeySet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
14807 | 297 | { |
14808 | 297 | unsigned lastoffset = 0; |
14809 | 297 | uint8_t tag_no, tag_info; |
14810 | 297 | uint32_t lvt; |
14811 | 297 | proto_tree *subtree; |
14812 | | |
14813 | 297 | subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_tag, NULL, "security keyset"); |
14814 | | |
14815 | 978 | while (tvb_reported_length_remaining(tvb, offset) > 0 && offset > lastoffset) { |
14816 | 955 | lastoffset = offset; |
14817 | | /* check the tag. A closing tag means we are done */ |
14818 | 955 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
14819 | 955 | if (tag_is_closing(tag_info)) { |
14820 | 2 | return offset; |
14821 | 2 | } |
14822 | 953 | switch (tag_no) { |
14823 | 606 | case 0: /* key-revision */ |
14824 | 606 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "key-revision: "); |
14825 | 606 | break; |
14826 | 22 | case 1: /* activation-time */ |
14827 | 22 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
14828 | 22 | offset = fDateTime(tvb, pinfo, subtree, offset, "activation-time: "); |
14829 | 22 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
14830 | 22 | break; |
14831 | 32 | case 2: /* expiration-time */ |
14832 | 32 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
14833 | 32 | offset = fDateTime(tvb, pinfo, subtree, offset, "expiration-time: "); |
14834 | 32 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
14835 | 32 | break; |
14836 | 22 | case 3: /* key-ids */ |
14837 | 22 | if (tag_is_opening(tag_info)) { |
14838 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
14839 | 0 | offset = fKeyIdentifier(tvb, pinfo, subtree, offset); |
14840 | 0 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
14841 | 22 | } else { |
14842 | 22 | expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag); |
14843 | 22 | } |
14844 | 22 | break; |
14845 | 271 | default: |
14846 | 271 | return offset; |
14847 | 953 | } |
14848 | 953 | } |
14849 | | |
14850 | 23 | return offset; |
14851 | 297 | } |
14852 | | |
14853 | | static unsigned |
14854 | | fSelectionCriteria(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
14855 | 62 | { |
14856 | 62 | unsigned lastoffset = 0; |
14857 | 62 | uint8_t tag_no, tag_info; |
14858 | 62 | uint32_t lvt; |
14859 | | |
14860 | 286 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
14861 | 285 | lastoffset = offset; |
14862 | 285 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
14863 | | /* quit loop if we spot a closing tag */ |
14864 | 285 | if (tag_is_closing(tag_info)) { |
14865 | 12 | break; |
14866 | 12 | } |
14867 | | |
14868 | 273 | switch (fTagNo(tvb, offset)) { |
14869 | 72 | case 0: /* propertyIdentifier */ |
14870 | 72 | offset = fPropertyIdentifier(tvb, pinfo, tree, offset); |
14871 | 72 | break; |
14872 | 118 | case 1: /* propertyArrayIndex */ |
14873 | 118 | offset = fPropertyArrayIndex(tvb, pinfo, tree, offset); |
14874 | 118 | break; |
14875 | 33 | case 2: /* relationSpecifier */ |
14876 | 33 | offset = fEnumeratedTag(tvb, pinfo, tree, offset, |
14877 | 33 | "relation Specifier: ", BACnetRelationSpecifier); |
14878 | 33 | break; |
14879 | 31 | case 3: /* comparisonValue */ |
14880 | 31 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
14881 | 31 | offset = fAbstractSyntaxNType(tvb, pinfo, tree, offset); |
14882 | 31 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
14883 | 31 | break; |
14884 | 19 | default: |
14885 | 19 | return offset; |
14886 | 273 | } |
14887 | 251 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
14888 | 251 | } |
14889 | 40 | return offset; |
14890 | 62 | } |
14891 | | |
14892 | | static unsigned |
14893 | | fObjectSelectionCriteria(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, unsigned offset) |
14894 | 46 | { |
14895 | 46 | unsigned lastoffset = 0; |
14896 | 46 | uint8_t tag_no, tag_info; |
14897 | 46 | uint32_t lvt; |
14898 | | |
14899 | 346 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
14900 | 344 | lastoffset = offset; |
14901 | 344 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
14902 | | /* quit loop if we spot a closing tag */ |
14903 | 344 | if (tag_is_closing(tag_info)) { |
14904 | 5 | break; |
14905 | 5 | } |
14906 | | |
14907 | 339 | switch (tag_no) { |
14908 | 242 | case 0: /* selectionLogic */ |
14909 | 242 | offset = fEnumeratedTag(tvb, pinfo, subtree, offset, |
14910 | 242 | "selection Logic: ", BACnetSelectionLogic); |
14911 | 242 | break; |
14912 | 72 | case 1: /* listOfSelectionCriteria */ |
14913 | 72 | if (tag_is_opening(tag_info)) { |
14914 | 62 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
14915 | 62 | offset = fSelectionCriteria(tvb, pinfo, subtree, offset); |
14916 | 62 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
14917 | 62 | } else { |
14918 | 10 | expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag); |
14919 | 10 | } |
14920 | 72 | break; |
14921 | 25 | default: |
14922 | 25 | return offset; |
14923 | 339 | } |
14924 | 310 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
14925 | 310 | } |
14926 | 17 | return offset; |
14927 | 46 | } |
14928 | | |
14929 | | |
14930 | | static unsigned |
14931 | | fReadPropertyConditionalRequest(tvbuff_t *tvb, packet_info* pinfo, proto_tree *subtree, unsigned offset) |
14932 | 49 | { |
14933 | 49 | unsigned lastoffset = 0; |
14934 | 49 | uint8_t tag_no, tag_info; |
14935 | 49 | uint32_t lvt; |
14936 | | |
14937 | 115 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
14938 | 112 | lastoffset = offset; |
14939 | 112 | fTagHeader (tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
14940 | | |
14941 | 112 | if (tag_is_opening(tag_info) && tag_no < 2) { |
14942 | 70 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
14943 | 70 | switch (tag_no) { |
14944 | 46 | case 0: /* objectSelectionCriteria */ |
14945 | 46 | offset = fObjectSelectionCriteria(tvb, pinfo, subtree, offset); |
14946 | 46 | break; |
14947 | 24 | case 1: /* listOfPropertyReferences */ |
14948 | 24 | offset = fBACnetPropertyReference(tvb, pinfo, subtree, offset, 1); |
14949 | 24 | break; |
14950 | 0 | default: |
14951 | 0 | return offset; |
14952 | 70 | } |
14953 | 66 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
14954 | 66 | } |
14955 | 108 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
14956 | 108 | } |
14957 | 45 | return offset; |
14958 | 49 | } |
14959 | | |
14960 | | static unsigned |
14961 | | fReadAccessSpecification(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
14962 | 167 | { |
14963 | 167 | unsigned lastoffset = 0; |
14964 | 167 | uint8_t tag_no, tag_info; |
14965 | 167 | uint32_t lvt; |
14966 | 167 | proto_tree *subtree = tree; |
14967 | | |
14968 | 850 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
14969 | 846 | lastoffset = offset; |
14970 | 846 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
14971 | 846 | switch (tag_no) { |
14972 | 347 | case 0: /* objectIdentifier */ |
14973 | 347 | offset = fObjectIdentifier(tvb, pinfo, subtree, offset, hf_bacapp_object_identifier); |
14974 | 347 | break; |
14975 | 352 | case 1: /* listOfPropertyReferences */ |
14976 | 352 | if (tag_is_opening(tag_info)) { |
14977 | 333 | subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "listOfPropertyReferences"); |
14978 | 333 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
14979 | 333 | offset = fBACnetPropertyReference(tvb, pinfo, subtree, offset, 1); |
14980 | 333 | } else if (tag_is_closing(tag_info)) { |
14981 | 7 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, |
14982 | 7 | &tag_no, &tag_info, &lvt); |
14983 | 7 | subtree = tree; |
14984 | 12 | } else { |
14985 | | /* error condition: let caller handle */ |
14986 | 12 | return offset; |
14987 | 12 | } |
14988 | 340 | break; |
14989 | 340 | default: |
14990 | 147 | return offset; |
14991 | 846 | } |
14992 | 683 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
14993 | 683 | } |
14994 | 4 | return offset; |
14995 | 167 | } |
14996 | | |
14997 | | static unsigned |
14998 | | // NOLINTNEXTLINE(misc-no-recursion) |
14999 | | fReadAccessResult(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
15000 | 713 | { |
15001 | 713 | unsigned lastoffset = 0, len; |
15002 | 713 | uint8_t tag_no; |
15003 | 713 | uint8_t tag_info; |
15004 | 713 | uint32_t lvt; |
15005 | 713 | proto_tree *subtree = tree; |
15006 | | |
15007 | 4.26k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
15008 | 4.26k | lastoffset = offset; |
15009 | 4.26k | len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
15010 | | /* maybe a listOfReadAccessResults if we spot a closing tag here */ |
15011 | 4.26k | if (tag_is_closing(tag_info)) { |
15012 | 1.52k | offset += len; |
15013 | 1.52k | if ((tag_no == 4 || tag_no == 5) && (subtree != tree)) |
15014 | 8 | subtree = subtree->parent; /* Value and error have extra subtree */ |
15015 | | |
15016 | 1.52k | if (tag_no == 1) { |
15017 | | /* closing list of results for this objectSpecifier */ |
15018 | 7 | fTagHeaderTree(tvb, pinfo, subtree, offset - len, &tag_no, &tag_info, &lvt); |
15019 | | /* look if another objectSpecifier follows here */ |
15020 | 7 | if (tvb_reported_length_remaining(tvb, offset) <= 0) |
15021 | 1 | return offset; /* nothing more to decode left */ |
15022 | | |
15023 | 6 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
15024 | 6 | if (tag_no != 0 || tag_info != 12) |
15025 | 6 | return offset; /* no objectSpecifier */ |
15026 | 6 | } |
15027 | | |
15028 | 1.51k | continue; |
15029 | 1.52k | } |
15030 | | |
15031 | 2.73k | switch (tag_no) { |
15032 | 1.64k | case 0: /* objectSpecifier */ |
15033 | 1.64k | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_object_identifier); |
15034 | 1.64k | break; |
15035 | 207 | case 1: /* list of Results */ |
15036 | 207 | if (tag_is_opening(tag_info)) { |
15037 | 101 | subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_value, NULL, "listOfResults"); |
15038 | 101 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
15039 | 106 | } else { |
15040 | 106 | expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag); |
15041 | 106 | } |
15042 | 207 | break; |
15043 | 315 | case 2: /* propertyIdentifier */ |
15044 | 315 | offset = fPropertyIdentifierValue(tvb, pinfo, subtree, offset, 2); |
15045 | 315 | break; |
15046 | 78 | case 5: /* propertyAccessError */ |
15047 | 78 | if (tag_is_opening(tag_info)) { |
15048 | 34 | subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "propertyAccessError"); |
15049 | 34 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
15050 | | /* Error Code follows */ |
15051 | 34 | offset = fError(tvb, pinfo, subtree, offset); |
15052 | 34 | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
15053 | 34 | } |
15054 | 44 | else { |
15055 | 44 | expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag); |
15056 | 44 | } |
15057 | 78 | break; |
15058 | 487 | default: |
15059 | 487 | return offset; |
15060 | 2.73k | } |
15061 | 2.24k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
15062 | 2.24k | } |
15063 | 210 | return offset; |
15064 | 713 | } |
15065 | | |
15066 | | |
15067 | | static unsigned |
15068 | | fReadPropertyConditionalAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
15069 | 7 | { |
15070 | | /* listOfReadAccessResults */ |
15071 | 7 | return fReadAccessResult(tvb, pinfo, tree, offset); |
15072 | 7 | } |
15073 | | |
15074 | | |
15075 | | static unsigned |
15076 | | fCreateObjectRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, unsigned offset) |
15077 | 51 | { |
15078 | 51 | unsigned lastoffset = 0; |
15079 | 51 | uint8_t tag_no, tag_info; |
15080 | 51 | uint32_t lvt; |
15081 | | |
15082 | 1.19k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
15083 | 1.19k | lastoffset = offset; |
15084 | 1.19k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
15085 | | |
15086 | 1.19k | if (tag_no < 2) { |
15087 | 1.15k | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
15088 | 1.15k | switch (tag_no) { |
15089 | 772 | case 0: /* objectSpecifier */ |
15090 | 772 | switch (fTagNo(tvb, offset)) { /* choice of objectType or objectIdentifier */ |
15091 | 649 | case 0: /* objectType */ |
15092 | 649 | offset = fEnumeratedTagSplit(tvb, pinfo, subtree, offset, "Object Type: ", BACnetObjectType, 128); |
15093 | 649 | break; |
15094 | 47 | case 1: /* objectIdentifier */ |
15095 | 47 | offset = fObjectIdentifier(tvb, pinfo, subtree, offset, hf_bacapp_object_identifier); |
15096 | 47 | break; |
15097 | 72 | default: |
15098 | 72 | break; |
15099 | 772 | } |
15100 | 768 | break; |
15101 | 768 | case 1: /* propertyValue */ |
15102 | 379 | if (tag_is_opening(tag_info)) { |
15103 | 151 | offset = fBACnetPropertyValue(tvb, pinfo, subtree, offset); |
15104 | 228 | } else { |
15105 | 228 | expert_add_info(pinfo, subtree, &ei_bacapp_bad_tag); |
15106 | 228 | } |
15107 | 379 | break; |
15108 | 0 | default: |
15109 | 0 | break; |
15110 | 1.15k | } |
15111 | 1.14k | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
15112 | 1.14k | } |
15113 | 1.18k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
15114 | 1.18k | } |
15115 | 46 | return offset; |
15116 | 51 | } |
15117 | | |
15118 | | static unsigned |
15119 | | fCreateObjectAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
15120 | 2 | { |
15121 | 2 | return fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_object_identifier); |
15122 | 2 | } |
15123 | | |
15124 | | static unsigned |
15125 | | fReadRangeRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
15126 | 34 | { |
15127 | 34 | uint8_t tag_no, tag_info; |
15128 | 34 | uint32_t lvt; |
15129 | 34 | proto_tree *subtree = tree; |
15130 | | |
15131 | 34 | offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset); |
15132 | | |
15133 | 34 | if (tvb_reported_length_remaining(tvb, offset) > 0) { |
15134 | | /* optional range choice */ |
15135 | 29 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
15136 | 29 | if (tag_is_opening(tag_info)) { |
15137 | 7 | subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, |
15138 | 7 | val_to_str_const(tag_no, BACnetReadRangeOptions, "unknown range option")); |
15139 | 7 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
15140 | 7 | switch (tag_no) { |
15141 | 0 | case 3: /* range byPosition */ |
15142 | 0 | case 6: /* range bySequenceNumber, 2004 spec */ |
15143 | 0 | offset = fApplicationTypes(tvb, pinfo, subtree, offset, "reference Index: "); |
15144 | 0 | offset = fApplicationTypes(tvb, pinfo, subtree, offset, "reference Count: "); |
15145 | 0 | break; |
15146 | 0 | case 4: /* range byTime - deprecated in 2004 */ |
15147 | 2 | case 7: /* 2004 spec */ |
15148 | 2 | offset = fDateTime(tvb, pinfo, subtree, offset, "reference Date/Time: "); |
15149 | 2 | offset = fApplicationTypes(tvb, pinfo, subtree, offset, "reference Count: "); |
15150 | 2 | break; |
15151 | 0 | case 5: /* range timeRange - deprecated in 2004 */ |
15152 | 0 | offset = fDateTime(tvb, pinfo, subtree, offset, "beginning Time: "); |
15153 | 0 | offset = fDateTime(tvb, pinfo, subtree, offset, "ending Time: "); |
15154 | 0 | break; |
15155 | 5 | default: |
15156 | 5 | break; |
15157 | 7 | } |
15158 | 7 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
15159 | 7 | } |
15160 | 29 | } |
15161 | 34 | return offset; |
15162 | 34 | } |
15163 | | |
15164 | | static unsigned |
15165 | | fReadRangeAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
15166 | 80 | { |
15167 | 80 | uint8_t tag_no, tag_info; |
15168 | 80 | uint32_t lvt; |
15169 | 80 | proto_tree *subtree = tree; |
15170 | | |
15171 | | /* set the optional global properties to indicate not-used */ |
15172 | 80 | propertyArrayIndex = -1; |
15173 | | /* objectIdentifier, propertyIdentifier, and |
15174 | | OPTIONAL propertyArrayIndex */ |
15175 | 80 | offset = fBACnetObjectPropertyReference(tvb, pinfo, subtree, offset); |
15176 | | /* resultFlags => BACnetResultFlags ::= BIT STRING */ |
15177 | 80 | offset = fBitStringTagVS(tvb, pinfo, tree, offset, |
15178 | 80 | "resultFlags: ", |
15179 | 80 | BACnetResultFlags); |
15180 | | /* itemCount */ |
15181 | 80 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "item Count: "); |
15182 | | /* itemData */ |
15183 | 80 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
15184 | 80 | if (tag_is_opening(tag_info)) { |
15185 | 67 | col_set_writable(pinfo->cinfo, COL_INFO, false); /* don't set all infos into INFO column */ |
15186 | 67 | subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, "itemData"); |
15187 | 67 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
15188 | 67 | offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset); |
15189 | 67 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
15190 | 67 | } |
15191 | | /* firstSequenceNumber - OPTIONAL */ |
15192 | 80 | if (tvb_reported_length_remaining(tvb, offset) > 0) { |
15193 | 51 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "first Sequence Number: "); |
15194 | 51 | } |
15195 | | |
15196 | 80 | return offset; |
15197 | 80 | } |
15198 | | |
15199 | | static unsigned |
15200 | | fAccessMethod(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
15201 | 37 | { |
15202 | 37 | unsigned lastoffset = 0; |
15203 | 37 | uint32_t lvt; |
15204 | 37 | uint8_t tag_no, tag_info; |
15205 | 37 | proto_tree* subtree = NULL; |
15206 | | |
15207 | 37 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
15208 | | |
15209 | 37 | if (tag_is_opening(tag_info)) { |
15210 | 25 | subtree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_bacapp_value, NULL, |
15211 | 25 | val_to_str_const(tag_no, BACnetFileAccessOption, "invalid access method")); |
15212 | 25 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
15213 | 25 | offset = fApplicationTypes(tvb, pinfo, subtree, offset, val_to_str_const(tag_no, BACnetFileStartOption, "invalid option")); |
15214 | 25 | offset = fApplicationTypes(tvb, pinfo, subtree, offset, val_to_str_const(tag_no, BACnetFileWriteInfo, "unknown option")); |
15215 | | |
15216 | 25 | if (tag_no == 1) { |
15217 | 70 | while ((tvb_reported_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { |
15218 | | /* exit loop if nothing happens inside */ |
15219 | 65 | lastoffset = offset; |
15220 | 65 | offset = fApplicationTypes(tvb, pinfo, subtree, offset, "Record Data: "); |
15221 | 65 | } |
15222 | 5 | } |
15223 | | |
15224 | 25 | if ((bacapp_flags & BACAPP_MORE_SEGMENTS) == 0) { |
15225 | | /* More Flag is not set, so we can look for closing tag in this segment */ |
15226 | 22 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
15227 | 22 | if (tag_is_closing(tag_info)) { |
15228 | 6 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
15229 | 6 | } |
15230 | 22 | } |
15231 | 25 | } |
15232 | 37 | return offset; |
15233 | 37 | } |
15234 | | |
15235 | | static unsigned |
15236 | | fAccessRule(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
15237 | 127 | { |
15238 | 127 | unsigned lastoffset = 0; |
15239 | 127 | uint8_t tag_no, tag_info; |
15240 | 127 | uint32_t lvt; |
15241 | | |
15242 | 1.93k | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
15243 | 1.92k | lastoffset = offset; |
15244 | 1.92k | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
15245 | | /* quit loop if we spot a closing tag */ |
15246 | 1.92k | if (tag_is_closing(tag_info)) { |
15247 | 18 | break; |
15248 | 18 | } |
15249 | | |
15250 | 1.90k | switch (tag_no) { |
15251 | 566 | case 0: /* time-range-specifier */ |
15252 | 566 | offset = fEnumeratedTag(tvb, pinfo, tree, offset, "time-range-specifier: ", NULL); |
15253 | 566 | break; |
15254 | 213 | case 1: /* time-range */ |
15255 | 213 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
15256 | 213 | offset = fDeviceObjectPropertyReference(tvb, pinfo, tree, offset); |
15257 | 213 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
15258 | 213 | break; |
15259 | 337 | case 2: /* location-specifier */ |
15260 | 337 | offset = fEnumeratedTag(tvb, pinfo, tree, offset, "location-specifier: ", NULL); |
15261 | 337 | break; |
15262 | 281 | case 3: /* location */ |
15263 | 281 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
15264 | 281 | offset = fDeviceObjectReference(tvb, pinfo, tree, offset); |
15265 | 281 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
15266 | 281 | break; |
15267 | 416 | case 4: /* enable */ |
15268 | 416 | offset = fBooleanTag(tvb, pinfo, tree, offset, "enable: "); |
15269 | 416 | break; |
15270 | 91 | default: |
15271 | 91 | break; |
15272 | 1.90k | } |
15273 | | |
15274 | 1.89k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
15275 | 1.89k | } |
15276 | | |
15277 | 118 | return offset; |
15278 | 127 | } |
15279 | | |
15280 | | static unsigned |
15281 | | fAtomicReadFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
15282 | 10 | { |
15283 | 10 | uint8_t tag_no, tag_info; |
15284 | 10 | uint32_t lvt; |
15285 | 10 | proto_tree *subtree = tree; |
15286 | | |
15287 | 10 | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_object_identifier); |
15288 | | |
15289 | 10 | fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
15290 | | |
15291 | 10 | if (tag_is_opening(tag_info)) { |
15292 | 6 | subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, ett_bacapp_value, NULL, |
15293 | 6 | val_to_str_const(tag_no, BACnetFileAccessOption, "unknown access method")); |
15294 | 6 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
15295 | 6 | offset = fSignedTag(tvb, pinfo, subtree, offset, val_to_str_const(tag_no, BACnetFileStartOption, "unknown option")); |
15296 | 6 | offset = fUnsignedTag(tvb, pinfo, subtree, offset, val_to_str_const(tag_no, BacnetFileRequestedCount, "unknown option")); |
15297 | 6 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
15298 | 6 | } |
15299 | 10 | return offset; |
15300 | 10 | } |
15301 | | |
15302 | | static unsigned |
15303 | | fAtomicWriteFileRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
15304 | 6 | { |
15305 | | |
15306 | 6 | offset = fObjectIdentifier(tvb, pinfo, tree, offset, hf_bacapp_object_identifier); /* file Identifier */ |
15307 | 6 | offset = fAccessMethod(tvb, pinfo, tree, offset); |
15308 | | |
15309 | 6 | return offset; |
15310 | 6 | } |
15311 | | |
15312 | | static unsigned |
15313 | | fAtomicWriteFileAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
15314 | 2 | { |
15315 | 2 | unsigned tag_no = fTagNo(tvb, offset); |
15316 | 2 | return fSignedTag(tvb, pinfo, tree, offset, val_to_str_const(tag_no, BACnetFileStartOption, "unknown option")); |
15317 | 2 | } |
15318 | | |
15319 | | static unsigned |
15320 | | fAtomicReadFileAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
15321 | 31 | { |
15322 | 31 | offset = fApplicationTypes(tvb, pinfo, tree, offset, "End Of File: "); |
15323 | 31 | offset = fAccessMethod(tvb, pinfo, tree, offset); |
15324 | | |
15325 | 31 | return offset; |
15326 | 31 | } |
15327 | | |
15328 | | static unsigned |
15329 | | fReadPropertyMultipleRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *subtree, unsigned offset) |
15330 | 38 | { |
15331 | 38 | col_set_writable(pinfo->cinfo, COL_INFO, false); /* don't set all infos into INFO column */ |
15332 | 38 | return fReadAccessSpecification(tvb, pinfo, subtree, offset); |
15333 | 38 | } |
15334 | | |
15335 | | static unsigned |
15336 | | fReadPropertyMultipleAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
15337 | 22 | { |
15338 | 22 | col_set_writable(pinfo->cinfo, COL_INFO, false); /* don't set all infos into INFO column */ |
15339 | 22 | return fReadAccessResult(tvb, pinfo, tree, offset); |
15340 | 22 | } |
15341 | | |
15342 | | static unsigned |
15343 | | fConfirmedServiceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, int service_choice) |
15344 | 7.16k | { |
15345 | 7.16k | if (tvb_reported_length_remaining(tvb, offset) <= 0) |
15346 | 21 | return offset; |
15347 | | |
15348 | 7.14k | switch (service_choice) { |
15349 | 228 | case 0: /* acknowledgeAlarm */ |
15350 | 228 | offset = fAcknowledgeAlarmRequest(tvb, pinfo, tree, offset); |
15351 | 228 | break; |
15352 | 239 | case 1: /* confirmedCOVNotification */ |
15353 | 239 | offset = fConfirmedCOVNotificationRequest(tvb, pinfo, tree, offset); |
15354 | 239 | break; |
15355 | 2.37k | case 2: /* confirmedEventNotification */ |
15356 | 2.37k | offset = fConfirmedEventNotificationRequest(tvb, pinfo, tree, offset); |
15357 | 2.37k | break; |
15358 | 0 | case 3: /* confirmedGetAlarmSummary conveys no parameters */ |
15359 | 0 | break; |
15360 | 108 | case 4: /* getEnrollmentSummaryRequest */ |
15361 | 108 | offset = fGetEnrollmentSummaryRequest(tvb, pinfo, tree, offset); |
15362 | 108 | break; |
15363 | 79 | case 5: /* subscribeCOVRequest */ |
15364 | 79 | offset = fSubscribeCOVRequest(tvb, pinfo, tree, offset); |
15365 | 79 | break; |
15366 | 10 | case 6: /* atomicReadFile-Request */ |
15367 | 10 | offset = fAtomicReadFileRequest(tvb, pinfo, tree, offset); |
15368 | 10 | break; |
15369 | 6 | case 7: /* atomicWriteFile-Request */ |
15370 | 6 | offset = fAtomicWriteFileRequest(tvb, pinfo, tree, offset); |
15371 | 6 | break; |
15372 | 1.19k | case 8: /* AddListElement-Request */ |
15373 | 1.19k | offset = fAddListElementRequest(tvb, pinfo, tree, offset); |
15374 | 1.19k | break; |
15375 | 39 | case 9: /* removeListElement-Request */ |
15376 | 39 | offset = fRemoveListElementRequest(tvb, pinfo, tree, offset); |
15377 | 39 | break; |
15378 | 51 | case 10: /* createObjectRequest */ |
15379 | 51 | offset = fCreateObjectRequest(tvb, pinfo, tree, offset); |
15380 | 51 | break; |
15381 | 2 | case 11: /* deleteObject */ |
15382 | 2 | offset = fDeleteObjectRequest(tvb, pinfo, tree, offset); |
15383 | 2 | break; |
15384 | 8 | case 12: |
15385 | 8 | offset = fReadPropertyRequest(tvb, pinfo, tree, offset); |
15386 | 8 | break; |
15387 | 49 | case 13: |
15388 | 49 | offset = fReadPropertyConditionalRequest(tvb, pinfo, tree, offset); |
15389 | 49 | break; |
15390 | 38 | case 14: |
15391 | 38 | offset = fReadPropertyMultipleRequest(tvb, pinfo, tree, offset); |
15392 | 38 | break; |
15393 | 83 | case 15: |
15394 | 83 | offset = fWritePropertyRequest(tvb, pinfo, tree, offset); |
15395 | 83 | break; |
15396 | 43 | case 16: |
15397 | 43 | offset = fWritePropertyMultipleRequest(tvb, pinfo, tree, offset); |
15398 | 43 | break; |
15399 | 44 | case 17: |
15400 | 44 | offset = fDeviceCommunicationControlRequest(tvb, pinfo, tree, offset); |
15401 | 44 | break; |
15402 | 78 | case 18: |
15403 | 78 | offset = fConfirmedPrivateTransferRequest(tvb, pinfo, tree, offset); |
15404 | 78 | break; |
15405 | 58 | case 19: |
15406 | 58 | offset = fConfirmedTextMessageRequest(tvb, pinfo, tree, offset); |
15407 | 58 | break; |
15408 | 31 | case 20: |
15409 | 31 | offset = fReinitializeDeviceRequest(tvb, pinfo, tree, offset); |
15410 | 31 | break; |
15411 | 8 | case 21: |
15412 | 8 | offset = fVtOpenRequest(tvb, pinfo, tree, offset); |
15413 | 8 | break; |
15414 | 26 | case 22: |
15415 | 26 | offset = fVtCloseRequest(tvb, pinfo, tree, offset); |
15416 | 26 | break; |
15417 | 14 | case 23: |
15418 | 14 | offset = fVtDataRequest(tvb, pinfo, tree, offset); |
15419 | 14 | break; |
15420 | 58 | case 24: |
15421 | 58 | offset = fAuthenticateRequest(tvb, pinfo, tree, offset); |
15422 | 58 | break; |
15423 | 7 | case 25: |
15424 | 7 | offset = fRequestKeyRequest(tvb, pinfo, tree, offset); |
15425 | 7 | break; |
15426 | 34 | case 26: |
15427 | 34 | offset = fReadRangeRequest(tvb, pinfo, tree, offset); |
15428 | 34 | break; |
15429 | 50 | case 27: |
15430 | 50 | offset = fLifeSafetyOperationRequest(tvb, pinfo, tree, offset, NULL); |
15431 | 50 | break; |
15432 | 30 | case 28: |
15433 | 30 | offset = fSubscribeCOVPropertyRequest(tvb, pinfo, tree, offset); |
15434 | 30 | break; |
15435 | 37 | case 29: |
15436 | 37 | offset = fGetEventInformationRequest(tvb, pinfo, tree, offset); |
15437 | 37 | break; |
15438 | 133 | case 30: |
15439 | 133 | offset = fSubscribeCOVPropertyMultipleRequest(tvb, pinfo, tree, offset); |
15440 | 133 | break; |
15441 | 74 | case 31: |
15442 | 74 | offset = fConfirmedCOVNotificationMultipleRequest(tvb, pinfo, tree, offset); |
15443 | 74 | break; |
15444 | 1.50k | case 32: |
15445 | 1.50k | offset = fConfirmedAuditNotificationRequest(tvb, pinfo, tree, offset); |
15446 | 1.50k | break; |
15447 | 231 | case 33: |
15448 | 231 | offset = fAuditLogQueryRequest(tvb, pinfo, tree, offset); |
15449 | 231 | break; |
15450 | 79 | case 34: |
15451 | 79 | offset = fAuthRequestRequest(tvb, pinfo, tree, offset); |
15452 | 79 | break; |
15453 | 93 | default: |
15454 | 93 | return offset; |
15455 | 7.14k | } |
15456 | 3.77k | return offset; |
15457 | 7.14k | } |
15458 | | |
15459 | | static unsigned |
15460 | | fConfirmedServiceAck(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, int service_choice) |
15461 | 621 | { |
15462 | 621 | if (tvb_reported_length_remaining(tvb, offset) <= 0) |
15463 | 16 | return offset; |
15464 | | |
15465 | 605 | switch (service_choice) { |
15466 | 40 | case 3: /* confirmedEventNotificationAck */ |
15467 | 40 | offset = fGetAlarmSummaryAck(tvb, pinfo, tree, offset); |
15468 | 40 | break; |
15469 | 43 | case 4: /* getEnrollmentSummaryAck */ |
15470 | 43 | offset = fGetEnrollmentSummaryAck(tvb, pinfo, tree, offset); |
15471 | 43 | break; |
15472 | 31 | case 6: /* atomicReadFile */ |
15473 | 31 | offset = fAtomicReadFileAck(tvb, pinfo, tree, offset); |
15474 | 31 | break; |
15475 | 2 | case 7: /* atomicReadFileAck */ |
15476 | 2 | offset = fAtomicWriteFileAck(tvb, pinfo, tree, offset); |
15477 | 2 | break; |
15478 | 2 | case 10: /* createObject */ |
15479 | 2 | offset = fCreateObjectAck(tvb, pinfo, tree, offset); |
15480 | 2 | break; |
15481 | 39 | case 12: |
15482 | 39 | offset = fReadPropertyAck(tvb, pinfo, tree, offset); |
15483 | 39 | break; |
15484 | 7 | case 13: |
15485 | 7 | offset = fReadPropertyConditionalAck(tvb, pinfo, tree, offset); |
15486 | 7 | break; |
15487 | 22 | case 14: |
15488 | 22 | offset = fReadPropertyMultipleAck(tvb, pinfo, tree, offset); |
15489 | 22 | break; |
15490 | 4 | case 18: |
15491 | 4 | offset = fConfirmedPrivateTransferAck(tvb, pinfo, tree, offset); |
15492 | 4 | break; |
15493 | 2 | case 21: |
15494 | 2 | offset = fVtOpenAck(tvb, pinfo, tree, offset); |
15495 | 2 | break; |
15496 | 11 | case 23: |
15497 | 11 | offset = fVtDataAck(tvb, pinfo, tree, offset); |
15498 | 11 | break; |
15499 | 2 | case 24: |
15500 | 2 | offset = fAuthenticateAck(tvb, pinfo, tree, offset); |
15501 | 2 | break; |
15502 | 80 | case 26: |
15503 | 80 | offset = fReadRangeAck(tvb, pinfo, tree, offset); |
15504 | 80 | break; |
15505 | 76 | case 29: |
15506 | 76 | offset = fGetEventInformationACK(tvb, pinfo, tree, offset); |
15507 | 76 | break; |
15508 | 69 | case 33: |
15509 | 69 | offset = fAuditLogQueryAck(tvb, pinfo, tree, offset); |
15510 | 69 | break; |
15511 | 139 | case 34: |
15512 | 139 | offset = fAuthRequestAck(tvb, pinfo, tree, offset); |
15513 | 139 | break; |
15514 | 36 | default: |
15515 | 36 | return offset; |
15516 | 605 | } |
15517 | 362 | return offset; |
15518 | 605 | } |
15519 | | |
15520 | | static unsigned |
15521 | | fIAmRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
15522 | 24 | { |
15523 | | /* BACnetObjectIdentifier */ |
15524 | 24 | offset = fApplicationTypes(tvb, pinfo, tree, offset, "BACnet Object Identifier: "); |
15525 | | |
15526 | | /* MaxAPDULengthAccepted */ |
15527 | 24 | offset = fApplicationTypes(tvb, pinfo, tree, offset, "Maximum ADPU Length Accepted: "); |
15528 | | |
15529 | | /* segmentationSupported */ |
15530 | 24 | offset = fApplicationTypesEnumerated(tvb, pinfo, tree, offset, |
15531 | 24 | "Segmentation Supported: ", BACnetSegmentation); |
15532 | | |
15533 | | /* vendor ID */ |
15534 | 24 | return fVendorIdentifier(tvb, pinfo, tree, offset); |
15535 | 24 | } |
15536 | | |
15537 | | static unsigned |
15538 | | fIHaveRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
15539 | 5 | { |
15540 | | /* BACnetDeviceIdentifier */ |
15541 | 5 | offset = fApplicationTypes(tvb, pinfo, tree, offset, "Device Identifier: "); |
15542 | | |
15543 | | /* BACnetObjectIdentifier */ |
15544 | 5 | offset = fApplicationTypes(tvb, pinfo, tree, offset, "Object Identifier: "); |
15545 | | |
15546 | | /* ObjectName */ |
15547 | 5 | return fObjectName(tvb, pinfo, tree, offset); |
15548 | 5 | } |
15549 | | |
15550 | | static unsigned |
15551 | | fWhoIsRequest(tvbuff_t *tvb, packet_info* pinfo, proto_tree *tree, unsigned offset) |
15552 | 32 | { |
15553 | 32 | unsigned lastoffset = 0; |
15554 | 32 | unsigned val; |
15555 | 32 | uint8_t tag_len; |
15556 | | |
15557 | 32 | uint8_t tag_no, tag_info; |
15558 | 32 | uint32_t lvt; |
15559 | | |
15560 | 130 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
15561 | 125 | lastoffset = offset; |
15562 | | |
15563 | 125 | tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
15564 | | |
15565 | 125 | switch (tag_no) { |
15566 | 79 | case 0: |
15567 | | /* DeviceInstanceRangeLowLimit Optional */ |
15568 | 79 | if (fUnsigned32(tvb, offset+tag_len, lvt, &val)) |
15569 | 35 | col_append_fstr(pinfo->cinfo, COL_INFO, "%d ", val); |
15570 | 79 | offset = fDevice_Instance(tvb, pinfo, tree, offset, |
15571 | 79 | hf_Device_Instance_Range_Low_Limit); |
15572 | 79 | break; |
15573 | 27 | case 1: |
15574 | | /* DeviceInstanceRangeHighLimit Optional but |
15575 | | required if DeviceInstanceRangeLowLimit is there */ |
15576 | 27 | if (fUnsigned32(tvb, offset+tag_len, lvt, &val)) |
15577 | 13 | col_append_fstr(pinfo->cinfo, COL_INFO, "%d ", val); |
15578 | 27 | offset = fDevice_Instance(tvb, pinfo, tree, offset, |
15579 | 27 | hf_Device_Instance_Range_High_Limit); |
15580 | 27 | break; |
15581 | 18 | default: |
15582 | 18 | return offset; |
15583 | 125 | } |
15584 | 98 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
15585 | 98 | } |
15586 | 5 | return offset; |
15587 | 32 | } |
15588 | | |
15589 | | static unsigned |
15590 | | fUnconfirmedServiceRequest(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, int service_choice) |
15591 | 660 | { |
15592 | 660 | if (tvb_reported_length_remaining(tvb, offset) <= 0) |
15593 | 2 | return offset; |
15594 | | |
15595 | 658 | switch (service_choice) { |
15596 | 24 | case 0: /* I-Am-Request */ |
15597 | 24 | offset = fIAmRequest(tvb, pinfo, tree, offset); |
15598 | 24 | break; |
15599 | 5 | case 1: /* i-Have Request */ |
15600 | 5 | offset = fIHaveRequest(tvb, pinfo, tree, offset); |
15601 | 5 | break; |
15602 | 9 | case 2: /* unconfirmedCOVNotification */ |
15603 | 9 | offset = fUnconfirmedCOVNotificationRequest(tvb, pinfo, tree, offset); |
15604 | 9 | break; |
15605 | 105 | case 3: /* unconfirmedEventNotification */ |
15606 | 105 | offset = fUnconfirmedEventNotificationRequest(tvb, pinfo, tree, offset); |
15607 | 105 | break; |
15608 | 6 | case 4: /* unconfirmedPrivateTransfer */ |
15609 | 6 | offset = fUnconfirmedPrivateTransferRequest(tvb, pinfo, tree, offset); |
15610 | 6 | break; |
15611 | 6 | case 5: /* unconfirmedTextMessage */ |
15612 | 6 | offset = fUnconfirmedTextMessageRequest(tvb, pinfo, tree, offset); |
15613 | 6 | break; |
15614 | 3 | case 6: /* timeSynchronization */ |
15615 | 3 | offset = fTimeSynchronizationRequest(tvb, pinfo, tree, offset); |
15616 | 3 | break; |
15617 | 50 | case 7: /* who-Has */ |
15618 | 50 | offset = fWhoHas(tvb, pinfo, tree, offset); |
15619 | 50 | break; |
15620 | 32 | case 8: /* who-Is */ |
15621 | 32 | offset = fWhoIsRequest(tvb, pinfo, tree, offset); |
15622 | 32 | break; |
15623 | 2 | case 9: /* utcTimeSynchronization */ |
15624 | 2 | offset = fUTCTimeSynchronizationRequest(tvb, pinfo, tree, offset); |
15625 | 2 | break; |
15626 | 242 | case 10: |
15627 | 242 | offset = fWriteGroupRequest(tvb, pinfo, tree, offset); |
15628 | 242 | break; |
15629 | 24 | case 11: |
15630 | 24 | offset = fUnconfirmedCOVNotificationMultipleRequest(tvb, pinfo, tree, offset); |
15631 | 24 | break; |
15632 | 17 | case 12: |
15633 | 17 | offset = fUnconfirmedAuditNotificationRequest(tvb, pinfo, tree, offset); |
15634 | 17 | break; |
15635 | 14 | case 13: |
15636 | 14 | offset = fWhoAmIRequest(tvb, pinfo, tree, offset); |
15637 | 14 | break; |
15638 | 21 | case 14: |
15639 | 21 | offset = fYouAreRequest(tvb, pinfo, tree, offset); |
15640 | 21 | break; |
15641 | 98 | default: |
15642 | 98 | break; |
15643 | 658 | } |
15644 | 483 | return offset; |
15645 | 658 | } |
15646 | | |
15647 | | static unsigned |
15648 | | fStartConfirmed(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, unsigned offset, uint8_t ack, |
15649 | | int *svc, proto_item **tt) |
15650 | 7.93k | { |
15651 | 7.93k | proto_item *tc; |
15652 | 7.93k | proto_tree *bacapp_tree_control; |
15653 | 7.93k | int tmp; |
15654 | 7.93k | unsigned extra = 2; |
15655 | | |
15656 | 7.93k | bacapp_seq = 0; |
15657 | 7.93k | tmp = tvb_get_int8(tvb, offset); |
15658 | 7.93k | bacapp_flags = tmp & 0x0f; |
15659 | | |
15660 | 7.93k | if (ack == 0) { |
15661 | 7.25k | extra = 3; |
15662 | 7.25k | } |
15663 | 7.93k | *svc = tvb_get_int8(tvb, offset+extra); |
15664 | 7.93k | if (bacapp_flags & 0x08) |
15665 | 250 | *svc = tvb_get_int8(tvb, offset+extra+2); |
15666 | | |
15667 | 7.93k | proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN); |
15668 | 7.93k | tc = proto_tree_add_item(bacapp_tree, hf_bacapp_pduflags, tvb, offset, 1, ENC_BIG_ENDIAN); |
15669 | 7.93k | bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp_control); |
15670 | | |
15671 | 7.93k | proto_tree_add_item(bacapp_tree_control, hf_bacapp_SEG, tvb, offset, 1, ENC_BIG_ENDIAN); |
15672 | 7.93k | proto_tree_add_item(bacapp_tree_control, hf_bacapp_MOR, tvb, offset, 1, ENC_BIG_ENDIAN); |
15673 | 7.93k | if (ack == 0) { /* The following are for ConfirmedRequest, not Complex ack */ |
15674 | 7.25k | proto_tree_add_item(bacapp_tree_control, hf_bacapp_SA, tvb, offset++, 1, ENC_BIG_ENDIAN); |
15675 | 7.25k | proto_tree_add_item(bacapp_tree, hf_bacapp_response_segments, tvb, |
15676 | 7.25k | offset, 1, ENC_BIG_ENDIAN); |
15677 | 7.25k | proto_tree_add_item(bacapp_tree, hf_bacapp_max_adpu_size, tvb, |
15678 | 7.25k | offset, 1, ENC_BIG_ENDIAN); |
15679 | 7.25k | } |
15680 | 7.93k | offset++; |
15681 | 7.93k | proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb, offset++, 1, ENC_BIG_ENDIAN); |
15682 | 7.93k | if (bacapp_flags & 0x08) { |
15683 | 250 | bacapp_seq = tvb_get_uint8(tvb, offset); |
15684 | 250 | proto_tree_add_item(bacapp_tree, hf_bacapp_sequence_number, tvb, |
15685 | 250 | offset++, 1, ENC_BIG_ENDIAN); |
15686 | 250 | proto_tree_add_item(bacapp_tree, hf_bacapp_window_size, tvb, |
15687 | 250 | offset++, 1, ENC_BIG_ENDIAN); |
15688 | 250 | } |
15689 | 7.93k | *tt = proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb, |
15690 | 7.93k | offset++, 1, ENC_BIG_ENDIAN); |
15691 | 7.93k | return offset; |
15692 | 7.93k | } |
15693 | | |
15694 | | static unsigned |
15695 | | fContinueConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, unsigned offset, int svc) |
15696 | 7.16k | { /* BACnet-Confirmed-Request */ |
15697 | | /* ASHRAE 135-2001 20.1.2 */ |
15698 | | |
15699 | 7.16k | return fConfirmedServiceRequest(tvb, pinfo, bacapp_tree, offset, svc); |
15700 | 7.16k | } |
15701 | | |
15702 | | static unsigned |
15703 | | fConfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, unsigned offset) |
15704 | 7.13k | { /* BACnet-Confirmed-Request */ |
15705 | | /* ASHRAE 135-2001 20.1.2 */ |
15706 | 7.13k | int svc; |
15707 | 7.13k | proto_item *tt = 0; |
15708 | | |
15709 | 7.13k | offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 0, &svc, &tt); |
15710 | 7.13k | return fContinueConfirmedRequestPDU(tvb, pinfo, bacapp_tree, offset, svc); |
15711 | 7.13k | } |
15712 | | |
15713 | | static unsigned |
15714 | | fUnconfirmedRequestPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, unsigned offset) |
15715 | 660 | { /* BACnet-Unconfirmed-Request-PDU */ |
15716 | | /* ASHRAE 135-2001 20.1.3 */ |
15717 | | |
15718 | 660 | int tmp; |
15719 | | |
15720 | 660 | proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN); |
15721 | | |
15722 | 660 | tmp = tvb_get_uint8(tvb, offset); |
15723 | 660 | proto_tree_add_item(bacapp_tree, hf_bacapp_uservice, tvb, |
15724 | 660 | offset++, 1, ENC_BIG_ENDIAN); |
15725 | | /* Service Request follows... Variable Encoding 20.2ff */ |
15726 | 660 | return fUnconfirmedServiceRequest(tvb, pinfo, bacapp_tree, offset, tmp); |
15727 | 660 | } |
15728 | | |
15729 | | static unsigned |
15730 | | fSimpleAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, unsigned offset) |
15731 | 47 | { /* BACnet-Simple-Ack-PDU */ |
15732 | | /* ASHRAE 135-2001 20.1.4 */ |
15733 | | |
15734 | 47 | proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN); |
15735 | | |
15736 | 47 | proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb, |
15737 | 47 | offset++, 1, ENC_BIG_ENDIAN); |
15738 | 47 | proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb, |
15739 | 47 | offset++, 1, ENC_BIG_ENDIAN); |
15740 | | |
15741 | 47 | return offset; |
15742 | 47 | } |
15743 | | |
15744 | | static unsigned |
15745 | | fContinueComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, unsigned offset, int svc) |
15746 | 621 | { /* BACnet-Complex-Ack-PDU */ |
15747 | | /* ASHRAE 135-2001 20.1.5 */ |
15748 | | |
15749 | | /* Service ACK follows... */ |
15750 | 621 | return fConfirmedServiceAck(tvb, pinfo, bacapp_tree, offset, svc); |
15751 | 621 | } |
15752 | | |
15753 | | static unsigned |
15754 | | fComplexAckPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, unsigned offset) |
15755 | 549 | { /* BACnet-Complex-Ack-PDU */ |
15756 | | /* ASHRAE 135-2001 20.1.5 */ |
15757 | 549 | int svc; |
15758 | 549 | proto_item *tt = 0; |
15759 | | |
15760 | 549 | offset = fStartConfirmed(tvb, pinfo, bacapp_tree, offset, 1, &svc, &tt); |
15761 | 549 | return fContinueComplexAckPDU(tvb, pinfo, bacapp_tree, offset, svc); |
15762 | 549 | } |
15763 | | |
15764 | | static unsigned |
15765 | | fSegmentAckPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, unsigned offset) |
15766 | 26 | { /* BACnet-SegmentAck-PDU */ |
15767 | | /* ASHRAE 135-2001 20.1.6 */ |
15768 | | |
15769 | 26 | proto_item *tc; |
15770 | 26 | proto_tree *bacapp_tree_control; |
15771 | | |
15772 | 26 | tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN); |
15773 | 26 | bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp); |
15774 | | |
15775 | 26 | proto_tree_add_item(bacapp_tree_control, hf_bacapp_NAK, tvb, offset, 1, ENC_BIG_ENDIAN); |
15776 | 26 | proto_tree_add_item(bacapp_tree_control, hf_bacapp_SRV, tvb, offset++, 1, ENC_BIG_ENDIAN); |
15777 | 26 | proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb, |
15778 | 26 | offset++, 1, ENC_BIG_ENDIAN); |
15779 | 26 | proto_tree_add_item(bacapp_tree_control, hf_bacapp_sequence_number, tvb, |
15780 | 26 | offset++, 1, ENC_BIG_ENDIAN); |
15781 | 26 | proto_tree_add_item(bacapp_tree_control, hf_bacapp_window_size, tvb, |
15782 | 26 | offset++, 1, ENC_BIG_ENDIAN); |
15783 | 26 | return offset; |
15784 | 26 | } |
15785 | | |
15786 | | static unsigned |
15787 | | fContextTaggedError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
15788 | 1.81k | { |
15789 | 1.81k | uint8_t tag_info = 0; |
15790 | 1.81k | uint8_t parsed_tag = 0; |
15791 | 1.81k | uint32_t lvt = 0; |
15792 | | |
15793 | 1.81k | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &parsed_tag, &tag_info, &lvt); |
15794 | 1.81k | offset = fError(tvb, pinfo, tree, offset); |
15795 | 1.81k | return offset + fTagHeaderTree(tvb, pinfo, tree, offset, &parsed_tag, &tag_info, &lvt); |
15796 | 1.81k | } |
15797 | | |
15798 | | static unsigned |
15799 | | fConfirmedPrivateTransferError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
15800 | 114 | { |
15801 | 114 | unsigned lastoffset = 0; |
15802 | 114 | uint8_t tag_no = 0, tag_info = 0; |
15803 | 114 | uint32_t lvt = 0; |
15804 | 114 | proto_tree *subtree = tree; |
15805 | | |
15806 | 114 | unsigned vendor_identifier = 0; |
15807 | 114 | unsigned service_number = 0; |
15808 | 114 | uint8_t tag_len = 0; |
15809 | | |
15810 | 3.54k | while (tvb_reported_length_remaining(tvb, offset) > 0) { |
15811 | | /* exit loop if nothing happens inside */ |
15812 | 3.53k | lastoffset = offset; |
15813 | 3.53k | tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
15814 | 3.53k | switch (tag_no) { |
15815 | 1.10k | case 0: /* errorType */ |
15816 | 1.10k | offset = fContextTaggedError(tvb, pinfo, subtree, offset); |
15817 | 1.10k | break; |
15818 | 1.18k | case 1: /* vendorID */ |
15819 | 1.18k | fUnsigned32(tvb, offset+tag_len, lvt, &vendor_identifier); |
15820 | 1.18k | col_append_fstr(pinfo->cinfo, COL_INFO, "V=%u ", vendor_identifier); |
15821 | 1.18k | offset = fVendorIdentifier(tvb, pinfo, subtree, offset); |
15822 | 1.18k | break; |
15823 | 1.01k | case 2: /* serviceNumber */ |
15824 | 1.01k | fUnsigned32(tvb, offset+tag_len, lvt, &service_number); |
15825 | 1.01k | col_append_fstr(pinfo->cinfo, COL_INFO, "SN=%u ", service_number); |
15826 | 1.01k | offset = fUnsignedTag(tvb, pinfo, subtree, offset, "service Number: "); |
15827 | 1.01k | break; |
15828 | 164 | case 3: /* errorParameters */ |
15829 | 164 | if (tag_is_opening(tag_info)) { |
15830 | 8 | subtree = proto_tree_add_subtree(subtree, tvb, offset, 1, |
15831 | 8 | ett_bacapp_value, NULL, "error Parameters"); |
15832 | 8 | propertyIdentifier = -1; |
15833 | 8 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
15834 | 8 | offset = fAbstractSyntaxNType(tvb, pinfo, subtree, offset); |
15835 | 156 | } else if (tag_is_closing(tag_info)) { |
15836 | 152 | offset += fTagHeaderTree(tvb, pinfo, subtree, offset, |
15837 | 152 | &tag_no, &tag_info, &lvt); |
15838 | 152 | subtree = tree; |
15839 | 152 | } else { |
15840 | | /* error condition: let caller handle */ |
15841 | 4 | return offset; |
15842 | 4 | } |
15843 | 160 | break; |
15844 | 160 | default: |
15845 | 71 | return offset; |
15846 | 3.53k | } |
15847 | 3.43k | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
15848 | 3.43k | } |
15849 | 12 | return offset; |
15850 | 114 | } |
15851 | | |
15852 | | static unsigned |
15853 | | fCreateObjectError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
15854 | 52 | { |
15855 | 52 | unsigned lastoffset = 0; |
15856 | | |
15857 | 544 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
15858 | 536 | lastoffset = offset; |
15859 | 536 | switch (fTagNo(tvb, offset)) { |
15860 | 325 | case 0: /* errorType */ |
15861 | 325 | offset = fContextTaggedError(tvb, pinfo, tree, offset); |
15862 | 325 | break; |
15863 | 178 | case 1: /* firstFailedElementNumber */ |
15864 | 178 | offset = fUnsignedTag(tvb, pinfo, tree, offset, "first failed element number: "); |
15865 | 178 | break; |
15866 | 33 | default: |
15867 | 33 | return offset; |
15868 | 536 | } |
15869 | 492 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
15870 | 492 | } |
15871 | 8 | return offset; |
15872 | 52 | } |
15873 | | |
15874 | | static unsigned |
15875 | | fChangeListError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
15876 | 39 | { |
15877 | | /* Identical to CreateObjectError */ |
15878 | 39 | return fCreateObjectError(tvb, pinfo, tree, offset); |
15879 | 39 | } |
15880 | | |
15881 | | static unsigned |
15882 | | fVTCloseError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
15883 | 21 | { |
15884 | 21 | uint8_t tag_no = 0, tag_info = 0; |
15885 | 21 | uint32_t lvt = 0; |
15886 | | |
15887 | 21 | if (fTagNo(tvb, offset) == 0) { |
15888 | | /* errorType */ |
15889 | 20 | offset = fContextTaggedError(tvb, pinfo, tree, offset); |
15890 | 20 | if (fTagNo(tvb, offset) == 1) { |
15891 | | /* listOfVTSessionIdentifiers [OPTIONAL] */ |
15892 | 16 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
15893 | 16 | offset = fVtCloseRequest(tvb, pinfo, tree, offset); |
15894 | 16 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
15895 | 16 | } |
15896 | 20 | } |
15897 | | /* should report bad packet if initial tag wasn't 0 */ |
15898 | 21 | return offset; |
15899 | 21 | } |
15900 | | |
15901 | | static unsigned |
15902 | | fWritePropertyMultipleError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
15903 | 30 | { |
15904 | 30 | unsigned lastoffset = 0; |
15905 | 30 | uint8_t tag_no = 0, tag_info = 0; |
15906 | 30 | uint32_t lvt = 0; |
15907 | | |
15908 | 30 | col_set_writable(pinfo->cinfo, COL_INFO, false); /* don't set all infos into INFO column */ |
15909 | 277 | while (tvb_reported_length_remaining(tvb, offset) > 0) { /* exit loop if nothing happens inside */ |
15910 | 274 | lastoffset = offset; |
15911 | 274 | switch (fTagNo(tvb, offset)) { |
15912 | 158 | case 0: /* errorType */ |
15913 | 158 | offset = fContextTaggedError(tvb, pinfo, tree, offset); |
15914 | 158 | break; |
15915 | 94 | case 1: /* firstFailedWriteAttempt */ |
15916 | 94 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
15917 | 94 | offset = fBACnetObjectPropertyReference(tvb, pinfo, tree, offset); |
15918 | 94 | offset += fTagHeaderTree(tvb, pinfo, tree, offset, &tag_no, &tag_info, &lvt); |
15919 | 94 | break; |
15920 | 22 | default: |
15921 | 22 | return offset; |
15922 | 274 | } |
15923 | 247 | if (offset <= lastoffset) break; /* nothing happened, exit loop */ |
15924 | 247 | } |
15925 | 3 | return offset; |
15926 | 30 | } |
15927 | | |
15928 | | static unsigned |
15929 | | fErrorClass(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
15930 | 2.43k | { |
15931 | 2.43k | uint32_t val = 0, lvt; |
15932 | 2.43k | uint8_t tag_no, tag_info; |
15933 | 2.43k | proto_item *ti; |
15934 | 2.43k | proto_tree *subtree; |
15935 | 2.43k | unsigned tag_len; |
15936 | | |
15937 | 2.43k | tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
15938 | 2.43k | if (fUnsigned32(tvb, offset+tag_len, lvt, &val)) |
15939 | 767 | { |
15940 | 767 | ti = proto_tree_add_uint(tree, hf_bacapp_error_class, |
15941 | 767 | tvb, offset, lvt+tag_len, val); |
15942 | 767 | subtree = proto_item_add_subtree(ti, ett_bacapp_tag); |
15943 | 767 | } |
15944 | 1.67k | else |
15945 | 1.67k | { |
15946 | 1.67k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, |
15947 | 1.67k | ett_bacapp_tag, NULL, "Error Class - %u octets (Signed)", lvt); |
15948 | 1.67k | } |
15949 | 2.43k | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
15950 | 2.43k | offset += tag_len + lvt; |
15951 | | |
15952 | 2.43k | return offset; |
15953 | 2.43k | } |
15954 | | |
15955 | | static unsigned |
15956 | | fErrorCode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
15957 | 2.43k | { |
15958 | 2.43k | uint32_t val = 0, lvt; |
15959 | 2.43k | uint8_t tag_no, tag_info; |
15960 | 2.43k | proto_item *ti; |
15961 | 2.43k | proto_tree *subtree; |
15962 | 2.43k | unsigned tag_len; |
15963 | | |
15964 | 2.43k | tag_len = fTagHeader(tvb, pinfo, offset, &tag_no, &tag_info, &lvt); |
15965 | 2.43k | if (fUnsigned32(tvb, offset+tag_len, lvt, &val)) |
15966 | 730 | { |
15967 | 730 | ti = proto_tree_add_uint(tree, hf_bacapp_error_code, |
15968 | 730 | tvb, offset, lvt+tag_len, val); |
15969 | 730 | subtree = proto_item_add_subtree(ti, ett_bacapp_tag); |
15970 | 730 | } |
15971 | 1.70k | else |
15972 | 1.70k | { |
15973 | 1.70k | subtree = proto_tree_add_subtree_format(tree, tvb, offset, lvt+tag_len, |
15974 | 1.70k | ett_bacapp_tag, NULL, "Error Code - %u octets (Signed)", lvt); |
15975 | 1.70k | } |
15976 | 2.43k | fTagHeaderTree(tvb, pinfo, subtree, offset, &tag_no, &tag_info, &lvt); |
15977 | 2.43k | offset += tag_len + lvt; |
15978 | | |
15979 | 2.43k | return offset; |
15980 | 2.43k | } |
15981 | | |
15982 | | static unsigned |
15983 | | fError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset) |
15984 | 2.43k | { |
15985 | 2.43k | offset = fErrorClass(tvb, pinfo, tree, offset); |
15986 | | |
15987 | 2.43k | return fErrorCode(tvb, pinfo, tree, offset); |
15988 | 2.43k | } |
15989 | | |
15990 | | static unsigned |
15991 | | fBACnetError(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, unsigned offset, unsigned service) |
15992 | 344 | { |
15993 | 344 | switch (service) { |
15994 | 13 | case 8: |
15995 | 13 | offset = fChangeListError(tvb, pinfo, tree, offset); |
15996 | 13 | break; |
15997 | 26 | case 9: |
15998 | 26 | offset = fChangeListError(tvb, pinfo, tree, offset); |
15999 | 26 | break; |
16000 | 13 | case 10: |
16001 | 13 | offset = fCreateObjectError(tvb, pinfo, tree, offset); |
16002 | 13 | break; |
16003 | 30 | case 16: |
16004 | 30 | offset = fWritePropertyMultipleError(tvb, pinfo, tree, offset); |
16005 | 30 | break; |
16006 | 114 | case 18: |
16007 | 114 | offset = fConfirmedPrivateTransferError(tvb, pinfo, tree, offset); |
16008 | 114 | break; |
16009 | 21 | case 22: |
16010 | 21 | offset = fVTCloseError(tvb, pinfo, tree, offset); |
16011 | 21 | break; |
16012 | 87 | case 30: |
16013 | 87 | offset = fSubscribeCOVPropertyMultipleError(tvb, pinfo, tree, offset); |
16014 | 87 | break; |
16015 | 16 | case 34: |
16016 | 16 | offset = fAuthRequestError(tvb, pinfo, tree, offset); |
16017 | 16 | break; |
16018 | 24 | default: |
16019 | 24 | offset = fError(tvb, pinfo, tree, offset); |
16020 | 24 | break; |
16021 | 344 | } |
16022 | 287 | return offset; |
16023 | 344 | } |
16024 | | |
16025 | | static unsigned |
16026 | | fErrorPDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bacapp_tree, unsigned offset) |
16027 | 344 | { /* BACnet-Error-PDU */ |
16028 | | /* ASHRAE 135-2001 20.1.7 */ |
16029 | | |
16030 | 344 | proto_item *tc; |
16031 | 344 | proto_tree *bacapp_tree_control; |
16032 | 344 | uint8_t tmp; |
16033 | | |
16034 | 344 | tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN); |
16035 | 344 | bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp); |
16036 | | |
16037 | 344 | proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb, |
16038 | 344 | offset++, 1, ENC_BIG_ENDIAN); |
16039 | 344 | tmp = tvb_get_uint8(tvb, offset); |
16040 | 344 | proto_tree_add_item(bacapp_tree_control, hf_bacapp_service, tvb, |
16041 | 344 | offset++, 1, ENC_BIG_ENDIAN); |
16042 | | /* Error Handling follows... */ |
16043 | 344 | return fBACnetError(tvb, pinfo, bacapp_tree, offset, tmp); |
16044 | 344 | } |
16045 | | |
16046 | | static unsigned |
16047 | | fRejectPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, unsigned offset) |
16048 | 22 | { /* BACnet-Reject-PDU */ |
16049 | | /* ASHRAE 135-2001 20.1.8 */ |
16050 | | |
16051 | 22 | proto_item *tc; |
16052 | 22 | proto_tree *bacapp_tree_control; |
16053 | | |
16054 | 22 | tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, ENC_BIG_ENDIAN); |
16055 | 22 | bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp); |
16056 | | |
16057 | 22 | proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb, |
16058 | 22 | offset++, 1, ENC_BIG_ENDIAN); |
16059 | 22 | proto_tree_add_item(bacapp_tree_control, hf_BACnetRejectReason, tvb, |
16060 | 22 | offset++, 1, ENC_BIG_ENDIAN); |
16061 | 22 | return offset; |
16062 | 22 | } |
16063 | | |
16064 | | static unsigned |
16065 | | fAbortPDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *bacapp_tree, unsigned offset) |
16066 | 72 | { /* BACnet-Abort-PDU */ |
16067 | | /* ASHRAE 135-2001 20.1.9 */ |
16068 | | |
16069 | 72 | proto_item *tc; |
16070 | 72 | proto_tree *bacapp_tree_control; |
16071 | | |
16072 | 72 | tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, ENC_BIG_ENDIAN); |
16073 | 72 | bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp); |
16074 | | |
16075 | 72 | proto_tree_add_item(bacapp_tree_control, hf_bacapp_SRV, tvb, offset++, 1, ENC_BIG_ENDIAN); |
16076 | 72 | proto_tree_add_item(bacapp_tree_control, hf_bacapp_invoke_id, tvb, |
16077 | 72 | offset++, 1, ENC_BIG_ENDIAN); |
16078 | 72 | proto_tree_add_item(bacapp_tree_control, hf_BACnetAbortReason, tvb, |
16079 | 72 | offset++, 1, ENC_BIG_ENDIAN); |
16080 | 72 | return offset; |
16081 | 72 | } |
16082 | | |
16083 | | static unsigned |
16084 | | do_the_dissection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) |
16085 | 8.94k | { |
16086 | 8.94k | uint8_t flag, bacapp_type; |
16087 | 8.94k | unsigned offset = 0; |
16088 | | |
16089 | 8.94k | flag = tvb_get_int8(tvb, 0); |
16090 | 8.94k | bacapp_type = (flag >> 4) & 0x0f; |
16091 | | |
16092 | 8.94k | if (tvb == NULL) { |
16093 | 0 | return 0; |
16094 | 0 | } |
16095 | | |
16096 | | /* ASHRAE 135-2001 20.1.1 */ |
16097 | 8.94k | switch (bacapp_type) { |
16098 | 7.13k | case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST: /* BACnet-Confirmed-Service-Request */ |
16099 | 7.13k | offset = fConfirmedRequestPDU(tvb, pinfo, tree, offset); |
16100 | 7.13k | break; |
16101 | 660 | case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST: /* BACnet-Unconfirmed-Request-PDU */ |
16102 | 660 | offset = fUnconfirmedRequestPDU(tvb, pinfo, tree, offset); |
16103 | 660 | break; |
16104 | 47 | case BACAPP_TYPE_SIMPLE_ACK: /* BACnet-Simple-Ack-PDU */ |
16105 | 47 | offset = fSimpleAckPDU(tvb, pinfo, tree, offset); |
16106 | 47 | break; |
16107 | 549 | case BACAPP_TYPE_COMPLEX_ACK: /* BACnet-Complex-Ack-PDU */ |
16108 | 549 | offset = fComplexAckPDU(tvb, pinfo, tree, offset); |
16109 | 549 | break; |
16110 | 26 | case BACAPP_TYPE_SEGMENT_ACK: /* BACnet-SegmentAck-PDU */ |
16111 | 26 | offset = fSegmentAckPDU(tvb, pinfo, tree, offset); |
16112 | 26 | break; |
16113 | 344 | case BACAPP_TYPE_ERROR: /* BACnet-Error-PDU */ |
16114 | 344 | offset = fErrorPDU(tvb, pinfo, tree, offset); |
16115 | 344 | break; |
16116 | 22 | case BACAPP_TYPE_REJECT: /* BACnet-Reject-PDU */ |
16117 | 22 | offset = fRejectPDU(tvb, pinfo, tree, offset); |
16118 | 22 | break; |
16119 | 72 | case BACAPP_TYPE_ABORT: /* BACnet-Abort-PDU */ |
16120 | 72 | offset = fAbortPDU(tvb, pinfo, tree, offset); |
16121 | 72 | break; |
16122 | 8.94k | } |
16123 | 5.23k | return offset; |
16124 | 8.94k | } |
16125 | | |
16126 | | static int |
16127 | | dissect_bacapp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
16128 | 9.21k | { |
16129 | 9.21k | uint8_t flag, bacapp_type; |
16130 | 9.21k | unsigned save_fragmented = false, data_offset = 0, /*bacapp_apdu_size,*/ fragment = false; |
16131 | 9.21k | tvbuff_t *new_tvb = NULL; |
16132 | 9.21k | unsigned offset = 0; |
16133 | 9.21k | uint8_t bacapp_seqno = 0; |
16134 | 9.21k | uint8_t bacapp_service, bacapp_reason/*, bacapp_prop_win_size*/; |
16135 | 9.21k | uint8_t bacapp_invoke_id = 0; |
16136 | 9.21k | proto_item *ti; |
16137 | 9.21k | proto_tree *bacapp_tree = NULL; |
16138 | | |
16139 | 9.21k | int svc = 0; |
16140 | 9.21k | proto_item *tt = 0; |
16141 | 9.21k | int8_t ack = 0; |
16142 | | |
16143 | | /* Strings for BACnet Statistics */ |
16144 | 9.21k | static const char errstr[] = "ERROR: "; |
16145 | 9.21k | static const char rejstr[] = "REJECTED: "; |
16146 | 9.21k | static const char abortstr[] = "ABORTED: "; |
16147 | 9.21k | static const char sackstr[] = " (SimpleAck)"; |
16148 | 9.21k | static const char cackstr[] = " (ComplexAck)"; |
16149 | 9.21k | static const char uconfsreqstr[] = " (Unconfirmed Service Request)"; |
16150 | 9.21k | static const char confsreqstr[] = " (Confirmed Service Request)"; |
16151 | | |
16152 | 9.21k | col_set_str(pinfo->cinfo, COL_PROTOCOL, "BACnet-APDU"); |
16153 | 9.21k | col_clear(pinfo->cinfo, COL_INFO); |
16154 | | |
16155 | 9.21k | flag = tvb_get_uint8(tvb, 0); |
16156 | 9.21k | bacapp_type = (flag >> 4) & 0x0f; |
16157 | | |
16158 | | /* show some descriptive text in the INFO column */ |
16159 | 9.21k | col_add_fstr(pinfo->cinfo, COL_INFO, "%-16s", |
16160 | 9.21k | val_to_str_const(bacapp_type, BACnetTypeName, "# unknown APDU #")); |
16161 | | |
16162 | 9.21k | bacinfo.service_type = NULL; |
16163 | 9.21k | bacinfo.invoke_id = NULL; |
16164 | 9.21k | bacinfo.instance_ident = NULL; |
16165 | 9.21k | bacinfo.object_ident = NULL; |
16166 | | |
16167 | 9.21k | switch (bacapp_type) { |
16168 | 7.26k | case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST: |
16169 | | /* segmented messages have 2 additional bytes */ |
16170 | 7.26k | if (flag & BACAPP_SEGMENTED_REQUEST) { |
16171 | 122 | fragment = true; |
16172 | 122 | ack = 0; |
16173 | | /* bacapp_apdu_size = fGetMaxAPDUSize(tvb_get_uint8(tvb, offset + 1)); */ /* has 16 values, reserved are 50 Bytes */ |
16174 | 122 | bacapp_invoke_id = tvb_get_uint8(tvb, offset + 2); |
16175 | 122 | bacapp_seqno = tvb_get_uint8(tvb, offset + 3); |
16176 | | /* bacapp_prop_win_size = tvb_get_uint8(tvb, offset + 4); */ |
16177 | 122 | bacapp_service = tvb_get_uint8(tvb, offset + 5); |
16178 | 122 | data_offset = 6; |
16179 | 7.14k | } else { |
16180 | 7.14k | bacapp_invoke_id = tvb_get_uint8(tvb, offset + 2); |
16181 | 7.14k | bacapp_service = tvb_get_uint8(tvb, offset + 3); |
16182 | 7.14k | } |
16183 | 7.26k | col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", |
16184 | 7.26k | val_to_str_const(bacapp_service, |
16185 | 7.26k | BACnetConfirmedServiceChoice, |
16186 | 7.26k | bacapp_unknown_service_str), |
16187 | 7.26k | bacapp_invoke_id); |
16188 | | |
16189 | 7.26k | updateBacnetInfoValue(BACINFO_INVOKEID, |
16190 | 7.26k | wmem_strdup_printf(pinfo->pool, "Invoke ID: %d", bacapp_invoke_id)); |
16191 | | |
16192 | 7.26k | updateBacnetInfoValue(BACINFO_SERVICE, |
16193 | 7.26k | wmem_strconcat(pinfo->pool, |
16194 | 7.26k | val_to_str_const(bacapp_service, |
16195 | 7.26k | BACnetConfirmedServiceChoice, |
16196 | 7.26k | bacapp_unknown_service_str), |
16197 | 7.26k | confsreqstr, NULL)); |
16198 | 7.26k | break; |
16199 | 660 | case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST: |
16200 | 660 | bacapp_service = tvb_get_uint8(tvb, offset + 1); |
16201 | 660 | col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", |
16202 | 660 | val_to_str_const(bacapp_service, |
16203 | 660 | BACnetUnconfirmedServiceChoice, |
16204 | 660 | bacapp_unknown_service_str)); |
16205 | | |
16206 | 660 | updateBacnetInfoValue(BACINFO_SERVICE, |
16207 | 660 | wmem_strconcat(pinfo->pool, |
16208 | 660 | val_to_str_const(bacapp_service, |
16209 | 660 | BACnetUnconfirmedServiceChoice, |
16210 | 660 | bacapp_unknown_service_str), |
16211 | 660 | uconfsreqstr, NULL)); |
16212 | 660 | break; |
16213 | 47 | case BACAPP_TYPE_SIMPLE_ACK: |
16214 | 47 | bacapp_invoke_id = tvb_get_uint8(tvb, offset + 1); |
16215 | 47 | bacapp_service = tvb_get_uint8(tvb, offset + 2); |
16216 | 47 | col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */ |
16217 | 47 | val_to_str_const(bacapp_service, |
16218 | 47 | BACnetConfirmedServiceChoice, |
16219 | 47 | bacapp_unknown_service_str), |
16220 | 47 | bacapp_invoke_id); |
16221 | | |
16222 | 47 | updateBacnetInfoValue(BACINFO_INVOKEID, |
16223 | 47 | wmem_strdup_printf(pinfo->pool, |
16224 | 47 | "Invoke ID: %d", bacapp_invoke_id)); |
16225 | | |
16226 | 47 | updateBacnetInfoValue(BACINFO_SERVICE, |
16227 | 47 | wmem_strconcat(pinfo->pool, |
16228 | 47 | val_to_str_const(bacapp_service, |
16229 | 47 | BACnetConfirmedServiceChoice, |
16230 | 47 | bacapp_unknown_service_str), |
16231 | 47 | sackstr, NULL)); |
16232 | 47 | break; |
16233 | 682 | case BACAPP_TYPE_COMPLEX_ACK: |
16234 | | /* segmented messages have 2 additional bytes */ |
16235 | 682 | if (flag & BACAPP_SEGMENTED_REQUEST) { |
16236 | 133 | fragment = true; |
16237 | 133 | ack = 1; |
16238 | | /* bacapp_apdu_size = fGetMaxAPDUSize(0); */ /* has minimum of 50 Bytes */ |
16239 | 133 | bacapp_invoke_id = tvb_get_uint8(tvb, offset + 1); |
16240 | 133 | bacapp_seqno = tvb_get_uint8(tvb, offset + 2); |
16241 | | /* bacapp_prop_win_size = tvb_get_uint8(tvb, offset + 3); */ |
16242 | 133 | bacapp_service = tvb_get_uint8(tvb, offset + 4); |
16243 | 133 | data_offset = 5; |
16244 | 549 | } else { |
16245 | 549 | bacapp_invoke_id = tvb_get_uint8(tvb, offset + 1); |
16246 | 549 | bacapp_service = tvb_get_uint8(tvb, offset + 2); |
16247 | 549 | } |
16248 | 682 | col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */ |
16249 | 682 | val_to_str_const(bacapp_service, |
16250 | 682 | BACnetConfirmedServiceChoice, |
16251 | 682 | bacapp_unknown_service_str), |
16252 | 682 | bacapp_invoke_id); |
16253 | | |
16254 | 682 | updateBacnetInfoValue(BACINFO_INVOKEID, |
16255 | 682 | wmem_strdup_printf(pinfo->pool, "Invoke ID: %d", bacapp_invoke_id)); |
16256 | | |
16257 | 682 | updateBacnetInfoValue(BACINFO_SERVICE, |
16258 | 682 | wmem_strconcat(pinfo->pool, |
16259 | 682 | val_to_str_const(bacapp_service, |
16260 | 682 | BACnetConfirmedServiceChoice, |
16261 | 682 | bacapp_unknown_service_str), |
16262 | 682 | cackstr, NULL)); |
16263 | 682 | break; |
16264 | 26 | case BACAPP_TYPE_SEGMENT_ACK: |
16265 | | /* nothing more to add */ |
16266 | 26 | break; |
16267 | 344 | case BACAPP_TYPE_ERROR: |
16268 | 344 | bacapp_invoke_id = tvb_get_uint8(tvb, offset + 1); |
16269 | 344 | bacapp_service = tvb_get_uint8(tvb, offset + 2); |
16270 | 344 | col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */ |
16271 | 344 | val_to_str_const(bacapp_service, |
16272 | 344 | BACnetConfirmedServiceChoice, |
16273 | 344 | bacapp_unknown_service_str), |
16274 | 344 | bacapp_invoke_id); |
16275 | | |
16276 | 344 | updateBacnetInfoValue(BACINFO_INVOKEID, |
16277 | 344 | wmem_strdup_printf(pinfo->pool, "Invoke ID: %d", bacapp_invoke_id)); |
16278 | | |
16279 | 344 | updateBacnetInfoValue(BACINFO_SERVICE, |
16280 | 344 | wmem_strconcat(pinfo->pool, |
16281 | 344 | errstr, |
16282 | 344 | val_to_str_const(bacapp_service, |
16283 | 344 | BACnetConfirmedServiceChoice, |
16284 | 344 | bacapp_unknown_service_str), |
16285 | 344 | NULL)); |
16286 | 344 | break; |
16287 | 22 | case BACAPP_TYPE_REJECT: |
16288 | 22 | bacapp_invoke_id = tvb_get_uint8(tvb, offset + 1); |
16289 | 22 | bacapp_reason = tvb_get_uint8(tvb, offset + 2); |
16290 | 22 | col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */ |
16291 | 22 | val_to_split_str(pinfo->pool, bacapp_reason, |
16292 | 22 | 64, |
16293 | 22 | BACnetRejectReason, |
16294 | 22 | ASHRAE_Reserved_Fmt, |
16295 | 22 | Vendor_Proprietary_Fmt), bacapp_invoke_id); |
16296 | | |
16297 | 22 | updateBacnetInfoValue(BACINFO_INVOKEID, |
16298 | 22 | wmem_strdup_printf(pinfo->pool, "Invoke ID: %d", bacapp_invoke_id)); |
16299 | | |
16300 | 22 | updateBacnetInfoValue(BACINFO_SERVICE, |
16301 | 22 | wmem_strconcat(pinfo->pool, rejstr, |
16302 | 22 | val_to_split_str(pinfo->pool, bacapp_reason, 64, |
16303 | 22 | BACnetRejectReason, |
16304 | 22 | ASHRAE_Reserved_Fmt, |
16305 | 22 | Vendor_Proprietary_Fmt), |
16306 | 22 | NULL)); |
16307 | 22 | break; |
16308 | 72 | case BACAPP_TYPE_ABORT: |
16309 | 72 | bacapp_invoke_id = tvb_get_uint8(tvb, offset + 1); |
16310 | 72 | bacapp_reason = tvb_get_uint8(tvb, offset + 2); |
16311 | 72 | col_append_fstr(pinfo->cinfo, COL_INFO, "%s[%3u] ", /* "original-invokeID" replaced */ |
16312 | 72 | val_to_split_str(pinfo->pool, bacapp_reason, |
16313 | 72 | 64, |
16314 | 72 | BACnetAbortReason, |
16315 | 72 | ASHRAE_Reserved_Fmt, |
16316 | 72 | Vendor_Proprietary_Fmt), bacapp_invoke_id); |
16317 | | |
16318 | 72 | updateBacnetInfoValue(BACINFO_INVOKEID, |
16319 | 72 | wmem_strdup_printf(pinfo->pool, "Invoke ID: %d", bacapp_invoke_id)); |
16320 | | |
16321 | 72 | updateBacnetInfoValue(BACINFO_SERVICE, |
16322 | 72 | wmem_strconcat(pinfo->pool, abortstr, |
16323 | 72 | val_to_split_str(pinfo->pool, bacapp_reason, |
16324 | 72 | 64, |
16325 | 72 | BACnetAbortReason, |
16326 | 72 | ASHRAE_Reserved_Fmt, |
16327 | 72 | Vendor_Proprietary_Fmt), |
16328 | 72 | NULL)); |
16329 | 72 | break; |
16330 | | /* UNKNOWN */ |
16331 | 88 | default: |
16332 | | /* nothing more to add */ |
16333 | 88 | break; |
16334 | 9.21k | } |
16335 | | |
16336 | 9.19k | save_fragmented = pinfo->fragmented; |
16337 | | |
16338 | 9.19k | ti = proto_tree_add_item(tree, proto_bacapp, tvb, offset, -1, ENC_NA); |
16339 | 9.19k | bacapp_tree = proto_item_add_subtree(ti, ett_bacapp); |
16340 | | |
16341 | 9.19k | if (!fragment) |
16342 | 8.94k | do_the_dissection(tvb, pinfo, bacapp_tree); |
16343 | 250 | else |
16344 | 250 | fStartConfirmed(tvb, pinfo, bacapp_tree, offset, ack, &svc, &tt); |
16345 | | /* not resetting the offset so the remaining can be done */ |
16346 | | |
16347 | 9.19k | if (fragment) { /* fragmented */ |
16348 | 250 | fragment_head *frag_msg; |
16349 | 250 | uint32_t ext_seqno = bacapp_seqno; |
16350 | | |
16351 | 250 | pinfo->fragmented = true; |
16352 | | |
16353 | 250 | if (!PINFO_FD_VISITED(pinfo)) { |
16354 | 250 | frag_msg = fragment_get(&msg_reassembly_table, pinfo, bacapp_invoke_id, NULL); |
16355 | 250 | if (frag_msg && frag_msg->first_gap) { |
16356 | | /* If we have permanently lost segments then using the last |
16357 | | * contiguous sequence number isn't quite right - but we |
16358 | | * won't be able to defragment in that case anyway. |
16359 | | */ |
16360 | 47 | uint32_t prev_seqno = frag_msg->first_gap->offset; |
16361 | 47 | ext_seqno = calculate_extended_seqno(prev_seqno, bacapp_seqno); |
16362 | | |
16363 | 47 | if (ext_seqno != bacapp_seqno) { |
16364 | 14 | p_add_proto_data(wmem_file_scope(), pinfo, proto_bacapp, bacapp_seqno, GUINT_TO_POINTER(ext_seqno)); |
16365 | 14 | } |
16366 | 47 | } |
16367 | 250 | } else { |
16368 | | /* This is not really necessary (because the fragment number is not |
16369 | | * used by fragment_add_seq_check on the second pass) but makes the |
16370 | | * fragment number in the Info column be the extended one. |
16371 | | */ |
16372 | 0 | ext_seqno = GPOINTER_TO_UINT(p_get_proto_data(wmem_file_scope(), pinfo, proto_bacapp, bacapp_seqno)); |
16373 | 0 | if (ext_seqno == 0) { |
16374 | 0 | ext_seqno = bacapp_seqno; |
16375 | 0 | } |
16376 | 0 | } |
16377 | 250 | frag_msg = fragment_add_seq_check(&msg_reassembly_table, |
16378 | 250 | tvb, data_offset, |
16379 | 250 | pinfo, |
16380 | 250 | bacapp_invoke_id, /* ID for fragments belonging together */ |
16381 | 250 | NULL, |
16382 | 250 | ext_seqno, /* fragment sequence number */ |
16383 | 250 | tvb_reported_length_remaining(tvb, data_offset), /* fragment length - to the end */ |
16384 | 250 | flag & BACAPP_MORE_SEGMENTS); /* Last fragment reached? */ |
16385 | 250 | new_tvb = process_reassembled_data(tvb, data_offset, pinfo, |
16386 | 250 | "Reassembled BACapp", frag_msg, &msg_frag_items, |
16387 | 250 | NULL, tree); |
16388 | | |
16389 | 250 | if (new_tvb) { /* Reassembled */ |
16390 | 96 | col_append_str(pinfo->cinfo, COL_INFO, |
16391 | 96 | " (Message Reassembled)"); |
16392 | 154 | } else { /* Not last packet of reassembled Short Message */ |
16393 | 154 | col_append_fstr(pinfo->cinfo, COL_INFO, |
16394 | 154 | " (Message fragment %u)", ext_seqno); |
16395 | 154 | } |
16396 | 250 | if (new_tvb) { /* take it all */ |
16397 | 96 | switch (bacapp_type) { |
16398 | 24 | case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST: |
16399 | 24 | fContinueConfirmedRequestPDU(new_tvb, pinfo, bacapp_tree, 0, svc); |
16400 | 24 | break; |
16401 | 72 | case BACAPP_TYPE_COMPLEX_ACK: |
16402 | 72 | fContinueComplexAckPDU(new_tvb, pinfo, bacapp_tree, 0, svc); |
16403 | 72 | break; |
16404 | 0 | default: |
16405 | | /* do nothing */ |
16406 | 0 | break; |
16407 | 96 | } |
16408 | 96 | } |
16409 | 250 | } |
16410 | | |
16411 | 9.19k | pinfo->fragmented = save_fragmented; |
16412 | | |
16413 | | /* tapping */ |
16414 | 9.19k | tap_queue_packet(bacapp_tap, pinfo, &bacinfo); |
16415 | 9.19k | return tvb_captured_length(tvb); |
16416 | 9.19k | } |
16417 | | |
16418 | | void |
16419 | | proto_register_bacapp(void) |
16420 | 14 | { |
16421 | 14 | static hf_register_info hf[] = { |
16422 | 14 | { &hf_bacapp_type, |
16423 | 14 | { "APDU Type", "bacapp.type", |
16424 | 14 | FT_UINT8, BASE_DEC, VALS(BACnetTypeName), 0xf0, NULL, HFILL } |
16425 | 14 | }, |
16426 | 14 | { &hf_bacapp_pduflags, |
16427 | 14 | { "PDU Flags", "bacapp.pduflags", |
16428 | 14 | FT_UINT8, BASE_HEX, NULL, 0x0f, NULL, HFILL } |
16429 | 14 | }, |
16430 | 14 | { &hf_bacapp_SEG, |
16431 | 14 | { "Segmented Request", "bacapp.segmented_request", |
16432 | 14 | FT_BOOLEAN, 8, TFS(&segments_follow), 0x08, NULL, HFILL } |
16433 | 14 | }, |
16434 | 14 | { &hf_bacapp_MOR, |
16435 | 14 | { "More Segments", "bacapp.more_segments", |
16436 | 14 | FT_BOOLEAN, 8, TFS(&more_follow), 0x04, "More Segments Follow", HFILL } |
16437 | 14 | }, |
16438 | 14 | { &hf_bacapp_SA, |
16439 | 14 | { "SA", "bacapp.SA", |
16440 | 14 | FT_BOOLEAN, 8, TFS(&segmented_accept), 0x02, "Segmented Response accepted", HFILL } |
16441 | 14 | }, |
16442 | 14 | { &hf_bacapp_max_adpu_size, |
16443 | 14 | { "Size of Maximum ADPU accepted", "bacapp.max_adpu_size", |
16444 | 14 | FT_UINT8, BASE_DEC, VALS(BACnetMaxAPDULengthAccepted), 0x0f, NULL, HFILL } |
16445 | 14 | }, |
16446 | 14 | { &hf_bacapp_response_segments, |
16447 | 14 | { "Max Response Segments accepted", "bacapp.response_segments", |
16448 | 14 | FT_UINT8, BASE_DEC, VALS(BACnetMaxSegmentsAccepted), 0x70, NULL, HFILL } |
16449 | 14 | }, |
16450 | 14 | { &hf_bacapp_object_identifier, |
16451 | 14 | { "Object Identifier", "bacapp.objectIdentifier", |
16452 | 14 | FT_UINT32, BASE_CUSTOM, CF_FUNC(format_object_identifier), 0, NULL, HFILL } |
16453 | 14 | }, |
16454 | 14 | { &hf_bacapp_device_identifier, |
16455 | 14 | { "Device Identifier", "bacapp.deviceIdentifier", |
16456 | 14 | FT_UINT32, BASE_CUSTOM, CF_FUNC(format_object_identifier), 0, NULL, HFILL } |
16457 | 14 | }, |
16458 | 14 | { &hf_bacapp_objectType, |
16459 | 14 | { "Object Type", "bacapp.objectType", |
16460 | 14 | FT_UINT32, BASE_DEC|BASE_EXT_STRING, &BACnetObjectType_ext, 0xffc00000, NULL, HFILL } |
16461 | 14 | }, |
16462 | 14 | { &hf_bacapp_object_name, |
16463 | 14 | { "Object Name", "bacapp.object_name", |
16464 | 14 | FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } |
16465 | 14 | }, |
16466 | 14 | { &hf_bacapp_instanceNumber, |
16467 | 14 | { "Instance Number", "bacapp.instance_number", |
16468 | 14 | FT_UINT32, BASE_DEC, NULL, 0x003fffff, NULL, HFILL } |
16469 | 14 | }, |
16470 | 14 | { &hf_BACnetPropertyIdentifier, |
16471 | 14 | { "Property Identifier", "bacapp.property_identifier", |
16472 | 14 | FT_UINT32, BASE_DEC, VALS(BACnetPropertyIdentifier), 0, NULL, HFILL } |
16473 | 14 | }, |
16474 | 14 | { &hf_BACnetVendorIdentifier, |
16475 | 14 | { "Vendor Identifier", "bacapp.vendor_identifier", |
16476 | 14 | FT_UINT16, BASE_DEC|BASE_EXT_STRING, &BACnetVendorIdentifiers_ext, 0, NULL, HFILL } |
16477 | 14 | }, |
16478 | 14 | { &hf_BACnetRestartReason, |
16479 | 14 | { "Restart Reason", "bacapp.restart_reason", |
16480 | 14 | FT_UINT8, BASE_DEC, VALS(BACnetRestartReason), 0, NULL, HFILL } |
16481 | 14 | }, |
16482 | 14 | { &hf_bacapp_invoke_id, |
16483 | 14 | { "Invoke ID", "bacapp.invoke_id", |
16484 | 14 | FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } |
16485 | 14 | }, |
16486 | 14 | { &hf_bacapp_sequence_number, |
16487 | 14 | { "Sequence Number", "bacapp.sequence_number", |
16488 | 14 | FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } |
16489 | 14 | }, |
16490 | 14 | { &hf_bacapp_window_size, |
16491 | 14 | { "Proposed Window Size", "bacapp.window_size", |
16492 | 14 | FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } |
16493 | 14 | }, |
16494 | 14 | { &hf_bacapp_service, |
16495 | 14 | { "Service Choice", "bacapp.confirmed_service", |
16496 | 14 | FT_UINT8, BASE_DEC, VALS(BACnetConfirmedServiceChoice), 0x00, NULL, HFILL } |
16497 | 14 | }, |
16498 | 14 | { &hf_bacapp_uservice, |
16499 | 14 | { "Unconfirmed Service Choice", "bacapp.unconfirmed_service", |
16500 | 14 | FT_UINT8, BASE_DEC, VALS(BACnetUnconfirmedServiceChoice), 0x00, NULL, HFILL } |
16501 | 14 | }, |
16502 | 14 | { &hf_bacapp_NAK, |
16503 | 14 | { "NAK", "bacapp.NAK", |
16504 | 14 | FT_BOOLEAN, 8, NULL, 0x02, "negative ACK", HFILL } |
16505 | 14 | }, |
16506 | 14 | { &hf_bacapp_SRV, |
16507 | 14 | { "SRV", "bacapp.SRV", |
16508 | 14 | FT_BOOLEAN, 8, NULL, 0x01, "Server", HFILL } |
16509 | 14 | }, |
16510 | 14 | { &hf_bacapp_event_type, |
16511 | 14 | { "Event Type", "bacapp.event_type", |
16512 | 14 | FT_UINT32, BASE_DEC, VALS(BACnetEventType), 0, NULL, HFILL } |
16513 | 14 | }, |
16514 | 14 | { &hf_bacapp_notify_type, |
16515 | 14 | { "Notify Type", "bacapp.notify_type", |
16516 | 14 | FT_UINT8, BASE_DEC, VALS(BACnetNotifyType), 0, NULL, HFILL } |
16517 | 14 | }, |
16518 | 14 | { &hf_bacapp_error_class, |
16519 | 14 | { "Error Class", "bacapp.error_class", |
16520 | 14 | FT_UINT32, BASE_DEC, VALS(BACnetErrorClass), 0, NULL, HFILL } |
16521 | 14 | }, |
16522 | 14 | { &hf_bacapp_error_code, |
16523 | 14 | { "Error Code", "bacapp.error_code", |
16524 | 14 | FT_UINT32, BASE_DEC|BASE_EXT_STRING, &BACnetErrorCode_ext, 0, NULL, HFILL } |
16525 | 14 | }, |
16526 | 14 | { &hf_bacapp_present_value_null, |
16527 | 14 | { "Present Value (null)", "bacapp.present_value.null", |
16528 | 14 | FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } |
16529 | 14 | }, |
16530 | 14 | { &hf_bacapp_present_value_bool, |
16531 | 14 | { "Present Value (bool)", "bacapp.present_value.boolean", |
16532 | 14 | FT_BOOLEAN, BASE_NONE, NULL, 0, NULL, HFILL } |
16533 | 14 | }, |
16534 | 14 | { &hf_bacapp_present_value_unsigned, |
16535 | 14 | { "Present Value (uint)", "bacapp.present_value.uint", |
16536 | 14 | FT_UINT64, BASE_DEC, NULL, 0, NULL, HFILL } |
16537 | 14 | }, |
16538 | 14 | { &hf_bacapp_present_value_signed, |
16539 | 14 | { "Present Value (int)", "bacapp.present_value.int", |
16540 | 14 | FT_INT64, BASE_DEC, NULL, 0, NULL, HFILL } |
16541 | 14 | }, |
16542 | 14 | { &hf_bacapp_present_value_real, |
16543 | 14 | { "Present Value (real)", "bacapp.present_value.real", |
16544 | 14 | FT_DOUBLE, BASE_NONE, NULL, 0, NULL, HFILL } |
16545 | 14 | }, |
16546 | 14 | { &hf_bacapp_present_value_double, |
16547 | 14 | { "Present Value (double)", "bacapp.present_value.double", |
16548 | 14 | FT_DOUBLE, BASE_NONE, NULL, 0, NULL, HFILL } |
16549 | 14 | }, |
16550 | 14 | { &hf_bacapp_present_value_octet_string, |
16551 | 14 | { "Present Value (octet string)", "bacapp.present_value.octet_string", |
16552 | 14 | FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } |
16553 | 14 | }, |
16554 | 14 | { &hf_bacapp_present_value_char_string, |
16555 | 14 | { "Present Value (char string)", "bacapp.present_value.char_string", |
16556 | 14 | FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } |
16557 | 14 | }, |
16558 | 14 | { &hf_bacapp_present_value_bit_string, |
16559 | 14 | { "Present Value (bit string)", "bacapp.present_value.bit_string", |
16560 | 14 | FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } |
16561 | 14 | }, |
16562 | 14 | { &hf_bacapp_present_value_enum_index, |
16563 | 14 | { "Present Value (enum index)", "bacapp.present_value.enum_index", |
16564 | 14 | FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } |
16565 | 14 | }, |
16566 | 14 | { &hf_Device_Instance_Range_Low_Limit, |
16567 | 14 | { "Device Instance Range Low Limit", "bacapp.who_is.low_limit", |
16568 | 14 | FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } |
16569 | 14 | }, |
16570 | 14 | { &hf_Device_Instance_Range_High_Limit, |
16571 | 14 | { "Device Instance Range High Limit", "bacapp.who_is.high_limit", |
16572 | 14 | FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } |
16573 | 14 | }, |
16574 | 14 | { &hf_BACnetRejectReason, |
16575 | 14 | { "Reject Reason", "bacapp.reject_reason", |
16576 | 14 | FT_UINT8, BASE_DEC, VALS(BACnetRejectReason), 0x00, NULL, HFILL } |
16577 | 14 | }, |
16578 | 14 | { &hf_BACnetAbortReason, |
16579 | 14 | { "Abort Reason", "bacapp.abort_reason", |
16580 | 14 | FT_UINT8, BASE_DEC, VALS(BACnetAbortReason), 0x00, NULL, HFILL } |
16581 | 14 | }, |
16582 | 14 | { &hf_BACnetApplicationTagNumber, |
16583 | 14 | { "Application Tag Number", |
16584 | 14 | "bacapp.application_tag_number", |
16585 | 14 | FT_UINT8, BASE_DEC, VALS(BACnetApplicationTagNumber), 0xF0, |
16586 | 14 | NULL, HFILL } |
16587 | 14 | }, |
16588 | 14 | { &hf_BACnetContextTagNumber, |
16589 | 14 | { "Context Tag Number", |
16590 | 14 | "bacapp.context_tag_number", |
16591 | 14 | FT_UINT8, BASE_DEC, NULL, 0xF0, |
16592 | 14 | NULL, HFILL } |
16593 | 14 | }, |
16594 | 14 | { &hf_BACnetExtendedTagNumber, |
16595 | 14 | { "Extended Tag Number", |
16596 | 14 | "bacapp.extended_tag_number", |
16597 | 14 | FT_UINT8, BASE_DEC, NULL, 0, |
16598 | 14 | NULL, HFILL } |
16599 | 14 | }, |
16600 | 14 | { &hf_BACnetNamedTag, |
16601 | 14 | { "Named Tag", |
16602 | 14 | "bacapp.named_tag", |
16603 | 14 | FT_UINT8, BASE_DEC, VALS(BACnetTagNames), 0x07, |
16604 | 14 | NULL, HFILL } |
16605 | 14 | }, |
16606 | 14 | { &hf_BACnetCharacterSet, |
16607 | 14 | { "String Character Set", |
16608 | 14 | "bacapp.string_character_set", |
16609 | 14 | FT_UINT8, BASE_DEC, VALS(BACnetCharacterSet), 0, |
16610 | 14 | NULL, HFILL } |
16611 | 14 | }, |
16612 | 14 | { &hf_BACnetCodePage, |
16613 | 14 | { "Code Page", |
16614 | 14 | "bacapp.code_page", |
16615 | 14 | FT_UINT16, BASE_DEC, NULL, 0, |
16616 | 14 | NULL, HFILL } |
16617 | 14 | }, |
16618 | 14 | { &hf_BACnetTagClass, |
16619 | 14 | { "Tag Class", "bacapp.tag_class", |
16620 | 14 | FT_BOOLEAN, 8, TFS(&BACnetTagClass), 0x08, NULL, HFILL } |
16621 | 14 | }, |
16622 | 14 | { &hf_bacapp_tag_lvt, |
16623 | 14 | { "Length Value Type", |
16624 | 14 | "bacapp.LVT", |
16625 | 14 | FT_UINT8, BASE_DEC, NULL, 0, |
16626 | 14 | NULL, HFILL } |
16627 | 14 | }, |
16628 | 14 | { &hf_bacapp_tag_ProcessId, |
16629 | 14 | { "ProcessIdentifier", "bacapp.processId", |
16630 | 14 | FT_UINT32, BASE_DEC, NULL, 0, "Process Identifier", HFILL } |
16631 | 14 | }, |
16632 | 14 | { &hf_bacapp_tag_to_state, |
16633 | 14 | { "To State", "bacapp.to_state", |
16634 | 14 | FT_UINT32, BASE_DEC, VALS(BACnetEventState), 0, NULL, HFILL } |
16635 | 14 | }, |
16636 | 14 | { &hf_bacapp_tag_from_state, |
16637 | 14 | { "From State", "bacapp.from_state", |
16638 | 14 | FT_UINT32, BASE_DEC, VALS(BACnetEventState), 0, NULL, HFILL } |
16639 | 14 | }, |
16640 | 14 | { &hf_bacapp_tag_IPV4, |
16641 | 14 | { "IPV4", "bacapp.IPV4", |
16642 | 14 | FT_IPv4, BASE_NONE, NULL, 0, "IP-Address", HFILL } |
16643 | 14 | }, |
16644 | 14 | { &hf_bacapp_tag_IPV6, |
16645 | 14 | { "IPV6", "bacapp.IPV6", |
16646 | 14 | FT_IPv6, BASE_NONE, NULL, 0, "IP-Address", HFILL } |
16647 | 14 | }, |
16648 | 14 | { &hf_bacapp_tag_PORT, |
16649 | 14 | { "Port", "bacapp.Port", |
16650 | 14 | FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } |
16651 | 14 | }, |
16652 | 14 | { &hf_bacapp_tag_mac_address_broadcast, |
16653 | 14 | { "MAC-address: broadcast", "bacapp.mac_address_broadcast", |
16654 | 14 | FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL } |
16655 | 14 | }, |
16656 | 14 | { &hf_bacapp_reserved_ashrea, |
16657 | 14 | { "reserved for ASHRAE", "bacapp.reserved_ashrea", |
16658 | 14 | FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } |
16659 | 14 | }, |
16660 | 14 | { &hf_bacapp_unused_bits, |
16661 | 14 | { "Unused bits", "bacapp.unused_bits", |
16662 | 14 | FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } |
16663 | 14 | }, |
16664 | 14 | { &hf_bacapp_bit, |
16665 | 14 | { "bit", "bacapp.bit", |
16666 | 14 | FT_BOOLEAN, BASE_NONE, NULL, 0, NULL, HFILL } |
16667 | 14 | }, |
16668 | 14 | { &hf_bacapp_complete_bitstring, |
16669 | 14 | { "Complete bitstring", "bacapp.complete_bitstring", |
16670 | 14 | FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } |
16671 | 14 | }, |
16672 | 14 | {&hf_msg_fragments, |
16673 | 14 | { "Message fragments", "bacapp.fragments", |
16674 | 14 | FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
16675 | 14 | {&hf_msg_fragment, |
16676 | 14 | { "Message fragment", "bacapp.fragment", |
16677 | 14 | FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
16678 | 14 | {&hf_msg_fragment_overlap, |
16679 | 14 | { "Message fragment overlap", "bacapp.fragment.overlap", |
16680 | 14 | FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
16681 | 14 | {&hf_msg_fragment_overlap_conflicts, |
16682 | 14 | { "Message fragment overlapping with conflicting data", |
16683 | 14 | "bacapp.fragment.overlap.conflicts", |
16684 | 14 | FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
16685 | 14 | {&hf_msg_fragment_multiple_tails, |
16686 | 14 | { "Message has multiple tail fragments", |
16687 | 14 | "bacapp.fragment.multiple_tails", |
16688 | 14 | FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
16689 | 14 | {&hf_msg_fragment_too_long_fragment, |
16690 | 14 | { "Message fragment too long", "bacapp.fragment.too_long_fragment", |
16691 | 14 | FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
16692 | 14 | {&hf_msg_fragment_error, |
16693 | 14 | { "Message defragmentation error", "bacapp.fragment.error", |
16694 | 14 | FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
16695 | 14 | {&hf_msg_fragment_count, |
16696 | 14 | { "Message fragment count", "bacapp.fragment.count", |
16697 | 14 | FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } }, |
16698 | 14 | {&hf_msg_reassembled_in, |
16699 | 14 | { "Reassembled in", "bacapp.reassembled.in", |
16700 | 14 | FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } }, |
16701 | 14 | {&hf_msg_reassembled_length, |
16702 | 14 | { "Reassembled BACapp length", "bacapp.reassembled.length", |
16703 | 14 | FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } } |
16704 | 14 | }; |
16705 | 14 | static int *ett[] = { |
16706 | 14 | &ett_bacapp, |
16707 | 14 | &ett_bacapp_control, |
16708 | 14 | &ett_bacapp_tag, |
16709 | 14 | &ett_bacapp_list, |
16710 | 14 | &ett_bacapp_value, |
16711 | 14 | &ett_bacapp_object_identifier, |
16712 | 14 | &ett_msg_fragment, |
16713 | 14 | &ett_msg_fragments |
16714 | | |
16715 | 14 | }; |
16716 | | |
16717 | 14 | static ei_register_info ei[] = { |
16718 | 14 | { &ei_bacapp_bad_length, { "bacapp.bad_length", PI_MALFORMED, PI_ERROR, "Wrong length indicated", EXPFILL }}, |
16719 | 14 | { &ei_bacapp_bad_tag, { "bacapp.bad_tag", PI_MALFORMED, PI_ERROR, "Wrong tag found", EXPFILL }}, |
16720 | 14 | { &ei_bacapp_opening_tag, { "bacapp.bad_opening_tag", PI_MALFORMED, PI_ERROR, "Expected Opening Tag!", EXPFILL }}, |
16721 | 14 | }; |
16722 | | |
16723 | 14 | expert_module_t* expert_bacapp; |
16724 | | |
16725 | 14 | proto_bacapp = proto_register_protocol("Building Automation and Control Network APDU", |
16726 | 14 | "BACapp", "bacapp"); |
16727 | | |
16728 | 14 | proto_register_field_array(proto_bacapp, hf, array_length(hf)); |
16729 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
16730 | 14 | expert_bacapp = expert_register_protocol(proto_bacapp); |
16731 | 14 | expert_register_field_array(expert_bacapp, ei, array_length(ei)); |
16732 | 14 | register_dissector("bacapp", dissect_bacapp, proto_bacapp); |
16733 | | |
16734 | 14 | reassembly_table_register(&msg_reassembly_table, |
16735 | 14 | &addresses_reassembly_table_functions); |
16736 | | |
16737 | 14 | bacapp_dissector_table = register_dissector_table("bacapp.vendor_identifier", |
16738 | 14 | "BACapp Vendor Identifier", proto_bacapp, |
16739 | 14 | FT_UINT8, BASE_HEX); |
16740 | | |
16741 | | /* Register BACnet Statistic trees */ |
16742 | 14 | register_bacapp_stat_trees(); |
16743 | 14 | bacapp_tap = register_tap("bacapp"); /* BACnet statistics tap */ |
16744 | 14 | } |
16745 | | |
16746 | | /* |
16747 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
16748 | | * |
16749 | | * Local variables: |
16750 | | * c-basic-offset: 4 |
16751 | | * tab-width: 8 |
16752 | | * indent-tabs-mode: nil |
16753 | | * End: |
16754 | | * |
16755 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
16756 | | * :indentSize=4:tabSize=8:noTabs=true: |
16757 | | */ |