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
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald[AT]wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * Copied from README.developer,v 1.23
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 #include "packet-bacapp.h"
32 /* some necessary forward function prototypes */
34 fApplicationTypesEnumerated (tvbuff_t *tvb, proto_tree *tree, guint offset,
35 const gchar *label, const value_string *vs);
37 static const char *bacapp_unknown_service_str = "unknown service";
38 static const char *ASHRAE_Reserved_Fmt = "(%d) Reserved for Use by ASHRAE";
39 static const char *Vendor_Proprietary_Fmt = "(%d) Vendor Proprietary Value";
41 static const value_string
43 {0, "Confirmed-Request "},
44 {1, "Unconfirmed-Request "},
54 static const true_false_string segments_follow = {
59 static const true_false_string more_follow = {
60 "More Segments Follow",
61 "No More Segments Follow"
64 static const true_false_string segmented_accept = {
65 "Segmented Response accepted",
66 "Segmented Response not accepted"
69 static const true_false_string
71 "Context Specific Tag",
75 static const value_string
76 BACnetMaxSegmentsAccepted [] = {
84 {7,"Greater than 64 segments"},
88 static const value_string
89 BACnetMaxAPDULengthAccepted [] = {
90 {0,"Up to MinimumMessageSize (50 octets)"},
91 {1,"Up to 128 octets"},
92 {2,"Up to 206 octets (fits in a LonTalk frame)"},
93 {3,"Up to 480 octets (fits in an ARCNET frame)"},
94 {4,"Up to 1024 octets"},
95 {5,"Up to 1476 octets (fits in an ISO 8802-3 frame)"},
96 {6,"reserved by ASHRAE"},
97 {7,"reserved by ASHRAE"},
98 {8,"reserved by ASHRAE"},
99 {9,"reserved by ASHRAE"},
100 {10,"reserved by ASHRAE"},
101 {11,"reserved by ASHRAE"},
102 {12,"reserved by ASHRAE"},
103 {13,"reserved by ASHRAE"},
104 {14,"reserved by ASHRAE"},
105 {15,"reserved by ASHRAE"},
109 static const value_string
110 BACnetRejectReason [] = {
112 {1,"buffer-overflow"},
113 {2,"inconsistent-parameters"},
114 {3,"invalid-parameter-data-type"},
116 {5,"missing-required-parameter"},
117 {6,"parameter-out-of-range"},
118 {7,"too-many-arguments"},
119 {8,"undefined-enumeration"},
120 {9,"unrecognized-service"},
124 static const value_string
125 BACnetApplicationTagNumber [] = {
128 {2,"Unsigned Integer"},
129 {3,"Signed Integer (2's complement notation)"},
130 {4,"Real (ANSI/IEE-754 floating point)"},
131 {5,"Double (ANSI/IEE-754 double precision floating point)"},
133 {7,"Character String"},
138 {12,"BACnetObjectIdentifier"},
139 {13,"reserved by ASHRAE"},
140 {14,"reserved by ASHRAE"},
141 {15,"reserved by ASHRAE"},
145 static const value_string
152 static const value_string
153 BACnetFileAccessMethod [] = {
159 /* For some reason, BACnet defines the choice parameter
160 in the file read and write services backwards from the
161 BACnetFileAccessMethod enumeration.
163 static const value_string
164 BACnetFileAccessOption [] = {
170 static const value_string
171 BACnetFileStartOption [] = {
172 {0, "File Start Position: "},
173 {1, "File Start Record: "},
177 static const value_string
178 BACnetFileRequestCount [] = {
179 {0, "Requested Octet Count: "},
180 {1, "Requested Record Count: "},
184 static const value_string
185 BACnetFileWriteInfo [] = {
187 {1, "Record Count: "},
191 static const value_string
192 BACnetAbortReason [] = {
194 {1,"buffer-overflow"},
195 {2,"invalid-apdu-in-this-state"},
196 {3,"preempted-by-higher-priority-task"},
197 {4,"segmentation-not-supported"},
201 static const value_string
202 BACnetLifeSafetyMode [] = {
216 {13,"atomic-release-disabled"},
219 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
220 Enumerated values 256-65535 may be used by others subject to
221 procedures and constraints described in Clause 23. */
224 static const value_string
225 BACnetLifeSafetyOperation [] = {
228 {2,"silence-audible"},
229 {3,"silence-visual"},
234 {8,"unsilence-audible"},
235 {9,"unsilence-visual"},
237 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
238 Enumerated values 64-65535 may be used by others subject to
239 procedures and constraints described in Clause 23. */
242 static const value_string
243 BACnetLimitEnable [] = {
244 {0,"lowLimitEnable"},
245 {1,"highLimitEnable"},
249 static const value_string
250 BACnetLifeSafetyState [] = {
255 {4,"fault-pre-alarm"},
263 {12,"test-fault-alarm"},
268 {17,"emergency-power"},
272 {21,"general-alarm"},
274 {23,"test-supervisory"},
276 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
277 Enumerated values 256-65535 may be used by others subject to
278 procedures and constraints described in Clause 23. */
281 static const value_string
282 BACnetConfirmedServiceChoice [] = {
283 {0,"acknowledgeAlarm"},
284 {1,"confirmedCOVNotification"},
285 {2,"confirmedEventNotification"},
286 {3,"getAlarmSummary"},
287 {4,"getEnrollmentSummary"},
289 {6,"atomicReadFile"},
290 {7,"atomicWriteFile"},
291 {8,"addListElement"},
292 {9,"removeListElement"},
296 {13,"readPropertyConditional"},
297 {14,"readPropertyMultiple"},
298 {15,"writeProperty"},
299 {16,"writePropertyMultiple"},
300 {17,"deviceCommunicationControl"},
301 {18,"confirmedPrivateTransfer"},
302 {19,"confirmedTextMessage"},
303 {20,"reinitializeDevice"},
310 {27,"lifeSafetyOperation"},
311 {28,"subscribeCOVProperty"},
312 {29,"getEventInformation"},
313 {30,"reserved by ASHRAE"},
317 static const value_string
318 BACnetReliability [] = {
319 {0,"no-fault-detected"},
326 {7,"unreliable-other"},
328 {9,"multi-state-fault"},
332 static const value_string
333 BACnetUnconfirmedServiceChoice [] = {
336 {2,"unconfirmedCOVNotification"},
337 {3,"unconfirmedEventNotification"},
338 {4,"unconfirmedPrivateTransfer"},
339 {5,"unconfirmedTextMessage"},
340 {6,"timeSynchronization"},
343 {9,"utcTimeSynchonization"},
347 static const value_string
348 BACnetUnconfirmedServiceRequest [] = {
350 {1,"i-Have-Request"},
351 {2,"unconfirmedCOVNotification-Request"},
352 {3,"unconfirmedEventNotification-Request"},
353 {4,"unconfirmedPrivateTransfer-Request"},
354 {5,"unconfirmedTextMessage-Request"},
355 {6,"timeSynchronization-Request"},
356 {7,"who-Has-Request"},
357 {8,"who-Is-Request"},
358 {9,"utcTimeSynchonization-Request"},
362 static const value_string
363 BACnetObjectType [] = {
364 {0,"analog-input object"},
365 {1,"analog-output object"},
366 {2,"analog-value object"},
367 {3,"binary-input object"},
368 {4,"binary-output object"},
369 {5,"binary-value object"},
370 {6,"calendar object"},
371 {7,"command object"},
373 {9,"event-enrollment object"},
377 {13,"multi-state-input object"},
378 {14,"multi-state-output object"},
379 {15,"notification-class object"},
380 {16,"program object"},
381 {17,"schedule object"},
382 {18,"averaging object"},
383 {19,"multi-state-value object"},
384 {20,"trend-log object"},
385 {21,"life-safety-point object"},
386 {22,"life-safety-zone object"},
387 {23,"accumulator object"},
388 {24,"pulse-converter object"},
389 {25,"event-log object"},
390 {26,"global-group object"},
391 {27,"trend-log-multiple object"},
392 {28,"load-control object"},
393 {29,"structured-view object"},
394 {30,"access-door object"},
396 /* Enumerated values 0-127 are reserved for definition by ASHRAE.
397 Enumerated values 128-1023 may be used by others subject to
398 the procedures and constraints described in Clause 23. */
401 static const value_string
402 BACnetEngineeringUnits [] = {
412 {9,"Kilovolt Amperes"},
413 {10,"Megavolt Amperes"},
414 {11,"Volt Amperes Reactive"},
415 {12,"Kilovolt Amperes Reactive"},
416 {13,"Megavolt Amperes Reactive"},
417 {14,"Degrees Phase"},
422 {19,"Kilowatt Hours"},
426 {23,"Joules Per Kg Dry Air"},
427 {24,"BTUs Per Pound Dry Air"},
428 {25,"Cycles Per Hour"},
429 {26,"Cycles Per Minute"},
431 {28,"Grams Of Water Per Kilogram Dry Air"},
432 {29,"Relative Humidity"},
437 {34,"Watts Per Sq Foot"},
438 {35,"Watts Per Sq meter"},
445 {42,"Kgs per Second"},
446 {43,"Kgs Per Minute"},
448 {45,"Pounds Mass Per Minute"},
449 {46,"Pounds Mass Per Hour"},
453 {50,"BTUs Per Hour"},
455 {52,"Tons Refrigeration"},
459 {56,"Pounds Force Per Square Inch"},
460 {57,"Centimeters Of Water"},
461 {58,"Inches Of Water"},
462 {59,"Millimeters Of Mercury"},
463 {60,"Centimeters Of Mercury"},
464 {61,"Inches Of Mercury"},
465 {62,"Degrees Celsius"},
466 {63,"Degrees Kelvin"},
467 {64,"Degrees Fahrenheit"},
468 {65,"Degree Days Celsius"},
469 {66,"Degree Days Fahrenheit"},
477 {74,"Meters Per Second"},
478 {75,"Kilometers Per Hour"},
479 {76,"Feed Per Second"},
480 {77,"Feet Per Minute"},
481 {78,"Miles Per Hour"},
484 {81,"Imperial Gallons"},
487 {84,"Cubic Feet Per Minute"},
488 {85,"Cubic Meters Per Second"},
489 {86,"Imperial Gallons Per Minute"},
490 {87,"Liters Per Second"},
491 {88,"Liters Per Minute"},
492 {89,"US Gallons Per Minute"},
493 {90,"Degrees Angular"},
494 {91,"Degrees Celsius Per Hour"},
495 {92,"Degrees Celsius Per Minute"},
496 {93,"Degrees Fahrenheit Per Hour"},
497 {94,"Degrees Fahrenheit Per Minute"},
499 {96,"Parts Per Million"},
500 {97,"Parts Per Billion"},
502 {99,"Pecent Per Second"},
505 {102,"Psi Per Degree Fahrenheit"},
507 {104,"Revolutions Per Min"},
519 {116,"Sq Centimeters"},
520 {117,"BTUs Per Pound"},
522 {119,"Pounds Mass Per Second"},
523 {120,"Delta Degrees Fahrenheit"},
524 {121,"Delta Degrees Kelvin"},
528 {125,"Kilojoules Per Kg"},
530 {127,"Joules Per Degree Kelvin"},
531 {128,"Joules Per Kg Degree Kelvin"},
536 {133,"Hectopascals"},
538 {135,"Cubic Meters Per Hour"},
539 {136,"Liters Per Hour"},
540 {137,"KWatt Hours Per Square Meter"},
541 {138,"KWatt Hours Per Square Foot"},
542 {139,"Megajoules Per Square Meter"},
543 {140,"Megajoules Per Square Foot"},
544 {141,"Watts Per Sq Meter Degree Kelvin"},
545 {142,"Cubic Feet Per Second"},
546 {143,"Percent Obstruction Per Foot"},
547 {144,"Percent Obstruction Per Meter"},
549 {146,"megawatt-hours"},
552 {149,"kilojoules-per-kilogram-dry-air"},
553 {150,"megajoules-per-kilogram-dry-air"},
554 {151,"kilojoules-per-degree-Kelvin"},
555 {152,"megajoules-per-degree-Kelvin"},
557 {154,"grams-per-second"},
558 {155,"grams-per-minute"},
559 {156,"tons-per-hour"},
560 {157,"kilo-btus-per-hour"},
561 {158,"hundredths-seconds"},
562 {159,"milliseconds"},
563 {160,"newton-meters"},
564 {161,"millimeters-per-second"},
565 {162,"millimeters-per-minute"},
566 {163,"meters-per-minute"},
567 {164,"meters-per-hour"},
568 {165,"cubic-meters-per-minute"},
569 {166,"meters-per-second-per-second"},
570 {167,"amperes-per-meter"},
571 {168,"amperes-per-square-meter"},
572 {169,"ampere-square-meters"},
577 {174,"siemens-per-meter"},
579 {176,"volts-per-degree-Kelvin"},
580 {177,"volts-per-meter"},
583 {180,"candelas-per-square-meter"},
584 {181,"degrees-Kelvin-per-hour"},
585 {182,"degrees-Kelvin-per-minute"},
586 {183,"joule-seconds"},
587 {184,"radians-per-second"},
588 {185,"square-meters-per-Newton"},
589 {186,"kilograms-per-cubic-meter"},
590 {187,"newton-seconds"},
591 {188,"newtons-per-meter"},
592 {189,"watts-per-meter-per-degree-Kelvin"},
594 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
595 Enumerated values 256-65535 may be used by others subject to
596 the procedures and constraints described in Clause 23. */
599 static const value_string
600 BACnetErrorCode [] = {
602 {1,"authentication-failed"},
603 {2,"configuration-in-progress"},
605 {4,"dynamic-creation-not-supported"},
606 {5,"file-access-denied"},
607 {6,"incompatible-security-levels"},
608 {7,"inconsistent-parameters"},
609 {8,"inconsistent-selection-criterion"},
610 {9,"invalid-data-type"},
611 {10,"invalid-file-access-method"},
612 {11,"invalid-file-start-position"},
613 {12,"invalid-operator-name"},
614 {13,"invalid-parameter-data-type"},
615 {14,"invalid-time-stamp"},
616 {15,"key-generation-error"},
617 {16,"missing-required-parameter"},
618 {17,"no-objects-of-specified-type"},
619 {18,"no-space-for-object"},
620 {19,"no-space-to-add-list-element"},
621 {20,"no-space-to-write-property"},
622 {21,"no-vt-sessions-available"},
623 {22,"property-is-not-a-list"},
624 {23,"object-deletion-not-permitted"},
625 {24,"object-identifier-already-exists"},
626 {25,"operational-problem"},
627 {26,"password-failure"},
628 {27,"read-access-denied"},
629 {28,"security-not-supported"},
630 {29,"service-request-denied"},
632 {31,"unknown-object"},
633 {32,"unknown-property"},
634 {33,"removed enumeration"},
635 {34,"unknown-vt-class"},
636 {35,"unknown-vt-session"},
637 {36,"unsupported-object-type"},
638 {37,"value-out-of-range"},
639 {38,"vt-session-already-closed"},
640 {39,"vt-session-termination-failure"},
641 {40,"write-access-denied"},
642 {41,"character-set-not-supported"},
643 {42,"invalid-array-index"},
644 {43,"cov-subscription-failed"},
645 {44,"not-cov-property"},
646 {45,"optional-functionality-not-supported"},
647 {46,"invalid-configuration-data"},
648 {47,"datatype-not-supported"},
649 {48,"duplicate-name"},
650 {49,"duplicate-object-id"},
651 {50,"property-is-not-an-array"},
652 {73,"invalid-event-state"},
653 {74,"no-alarm-configured"},
655 /* Enumerated values 0-255 are reserved for definition by ASHRAE.
656 Enumerated values 256-65535 may be used by others subject to the
657 procedures and constraints described in Clause 23. */
660 static const value_string
661 BACnetPropertyIdentifier [] = {
662 {0,"acked-transition"},
667 {5,"active-vt-session"},
671 {9,"all-write-successful"},
672 {10,"apdu-segment-timeout"},
674 {12,"application-software-version"},
677 {15,"change-of-state-count"},
678 {16,"change-of-state-time"},
679 {17,"notification-class"},
680 {18,"the property in this place was deleted"},
681 {19,"controlled-variable-reference"},
682 {20,"controlled-variable-units"},
683 {21,"controlled-variable-value"},
684 {22,"cov-increment"},
686 {24,"daylights-savings-status"},
688 {26,"derivative-constant"},
689 {27,"derivative-constant-units"},
691 {29,"description-of-halt"},
692 {30,"device-address-binding"},
694 {32,"effective-period"},
695 {33,"elapsed-active-time"},
700 {38,"exception-schedule"},
702 {40,"feedback-value"},
703 {41,"file-access-method"},
706 {44,"firmware-revision"},
708 {46,"inactive-text"},
711 {49,"integral-constant"},
712 {50,"integral-constant-units"},
713 {51,"issue-confirmed-notifications"},
715 {53,"list-of-group-members"},
716 {54,"list-of-object-property-references"},
717 {55,"list-of-session-keys"},
722 {60,"manipulated-variable-reference"},
723 {61,"maximum-output"},
724 {62,"max-apdu-length-accepted"},
725 {63,"max-info-frames"},
727 {65,"max-pres-value"},
728 {66,"minimum-off-time"},
729 {67,"minimum-on-time"},
730 {68,"minimum-output"},
731 {69,"min-pres-value"},
733 {71,"modification-date"},
735 {73,"number-of-APDU-retries"},
736 {74,"number-of-states"},
737 {75,"object-identifier"},
740 {78,"object-property-reference"},
743 {81,"out-of-service"},
745 {83,"event-parameters"},
747 {85,"present-value"},
749 {87,"priority-array"},
750 {88,"priority-for-writing"},
751 {89,"process-identifier"},
752 {90,"program-change"},
753 {91,"program-location"},
754 {92,"program-state"},
755 {93,"proportional-constant"},
756 {94,"proportional-constant-units"},
757 {95,"protocol-conformance-class"},
758 {96,"protocol-object-types-supported"},
759 {97,"protocol-services-supported"},
760 {98,"protocol-version"},
762 {100,"reason-for-halt"},
764 {102,"recipient-list"},
766 {104,"relinquish-default"},
769 {107,"segmentation-supported"},
771 {109,"setpoint-reference"},
773 {111,"status-flags"},
774 {112,"system-status"},
776 {114,"time-of-active-time-reset"},
777 {115,"time-of-state-count-reset"},
778 {116,"time-synchronization-recipients"},
780 {118,"update-interval"},
782 {120,"vendor-identifier"},
784 {122,"vt-class-supported"},
785 {123,"weekly-schedule"},
786 {124,"attempted-samples"},
787 {125,"average-value"},
789 {127,"client-cov-increment"},
790 {128,"cov-resubscription-interval"},
791 {129,"current-notify-time"},
792 {130,"event-time-stamp"},
794 {132,"log-device-object-property"},
795 {133,"enable"}, /* per ANSI/ASHRAE 135-2004 addendum B */
796 {134,"log-interval"},
797 {135,"maximum-value"},
798 {136,"minimum-value"},
799 {137,"notification-threshold"},
800 {138,"previous-notify-time"},
801 {139,"protocol-revision"},
802 {140,"records-since-notification"},
803 {141,"record-count"},
806 {144,"stop-when-full"},
807 {145,"total-record-count"},
808 {146,"valid-samples"},
809 {147,"window-interval"},
810 {148,"window-samples"},
811 {149,"maximum-value-time-stamp"},
812 {150,"minimum-value-time-stamp"},
813 {151,"variance-value"},
814 {152,"active-cov-subscriptions"},
815 {153,"backup-failure-timeout"},
816 {154,"configuration-files"},
817 {155,"database-revision"},
818 {156,"direct-reading"},
819 {157,"last-restore-time"},
820 {158,"maintenance-required"},
823 {161,"operation-expected"},
826 {164,"tracking-value"},
827 {165,"zone-members"},
828 {166,"life-safety-alarm-values"},
829 {167,"max-segments-accepted"},
830 {168,"profile-name"},
831 {169,"auto-slave-discovery"},
832 {170,"manual-slave-address-binding"},
833 {171,"slave-address-binding"},
834 {172,"slave-proxy-enable"},
835 {173,"last-notify-time"},
836 {174,"schedule-default"},
837 {175,"accepted-modes"},
838 {176,"adjust-value"},
840 {178,"count-before-change"},
841 {179,"count-change-time"},
843 {181,"input-reference"},
844 {182,"limit-monitoring-interval"},
845 {183,"logging-device"},
846 {184,"logging-record"},
850 {188,"scale-factor"},
852 {190,"value-before-change"},
854 {192,"value-change-time"},
855 {193,"align-intervals"},
856 {194,"group-member-names"},
857 {195,"interval-offset"},
858 {196,"last-restart-reason"},
859 {197,"logging-type"},
860 {198,"member-status-flags"},
861 {199,"notification-period"},
862 {200,"previous-notify-record"},
863 {201,"requested-update-interval"},
864 {202,"restart-notification-recipients"},
865 {203,"time-of-device-restart"},
866 {204,"time-synchronization-recipients"},
868 {206,"UTC-time-synchronization-recipients"},
869 {207,"node-subtype"},
871 {209,"structured-object-list"},
872 {210,"subordinate-annotations"},
873 {211,"subordinate-list"},
874 {212,"actual-shed-level"},
876 {214,"expected-shed-level"},
877 {215,"full-duty-baseline"},
878 {216,"node-subtype"},
880 {218,"requested-shed-level"},
881 {219,"shed-duration"},
882 {220,"shed-level-descriptions"},
884 {222,"state-description"},
885 {226,"door-alarm-state"},
886 {227,"door-extended-pulse-time"},
887 {228,"door-members"},
888 {229,"door-open-too-long-time"},
889 {230,"door-pulse-time"},
891 {232,"door-unlock-delay-time"},
893 {234,"masked-alarm-values"},
894 {235,"secured-status"},
896 /* Enumerated values 0-511 are reserved for definition by ASHRAE.
897 Enumerated values 512-4194303 may be used by others subject to
898 the procedures and constraints described in Clause 23. */
901 static const value_string
902 BACnetBinaryPV [] = {
910 #define IBM_MS_DBCS 1
912 #define ISO_10646_UCS4 3
913 #define ISO_10646_UCS2 4
914 #define ISO_18859_1 5
915 static const value_string
916 BACnetCharacterSet [] = {
917 {ANSI_X34, "ANSI X3.4"},
918 {IBM_MS_DBCS, "IBM/Microsoft DBCS"},
919 {JIS_C_6226, "JIS C 6226"},
920 {ISO_10646_UCS4, "ISO 10646(UCS-4)"},
921 {ISO_10646_UCS2, "ISO 10646(UCS-2)"},
922 {ISO_18859_1, "ISO 18859-1"},
926 static const value_string
927 BACnetStatusFlags [] = {
931 {3,"out-of-service"},
935 static const value_string
936 BACnetMessagePriority [] = {
942 static const value_string
943 BACnetAcknowledgementFilter [] = {
950 static const value_string
951 BACnetResultFlags [] = {
958 static const value_string
959 BACnetRelationSpecifier [] = {
964 {4,"less-than-or-equal"},
965 {5,"greater-than-or-equal"},
969 static const value_string
970 BACnetSelectionLogic [] = {
977 static const value_string
978 BACnetEventStateFilter [] = {
987 static const value_string
988 BACnetEventTransitionBits [] = {
995 static const value_string
996 BACnetSegmentation [] = {
997 {0,"segmented-both"},
998 {1,"segmented-transmit"},
999 {2,"segmented-receive"},
1000 {3,"no-segmentation"},
1004 static const value_string
1005 BACnetSilencedState [] = {
1007 {1,"audible-silenced"},
1008 {2,"visible-silenced"},
1013 static const value_string
1014 BACnetDeviceStatus [] = {
1016 {1,"operational-read-only"},
1017 {2,"download-required"},
1018 {3,"download-in-progress"},
1019 {4,"non-operational"},
1020 {5,"backup-in-progress"},
1024 static const value_string
1025 BACnetEnableDisable [] = {
1028 {2,"disable-initiation"},
1032 static const value_string
1050 static const value_string
1052 {1,"days numbered 1-7" },
1053 {2,"days numbered 8-14" },
1054 {3,"days numbered 15-21" },
1055 {4,"days numbered 22-28" },
1056 {5,"days numbered 29-31" },
1057 {6,"last 7 days of this month" },
1058 {255,"any week of this month" },
1062 /* note: notification class object recipient-list uses
1063 different day-of-week enum */
1064 static const value_string
1073 {255,"any day of week" },
1077 static const value_string
1078 BACnetErrorClass [] = {
1087 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
1088 Enumerated values64-65535 may be used by others subject to
1089 the procedures and constraints described in Clause 23. */
1092 static const value_string
1093 BACnetVTClass [] = {
1094 {0,"default-terminal" },
1104 static const value_string
1105 BACnetEventType [] = {
1106 {0,"change-of-bitstring" },
1107 {1,"change-of-state" },
1108 {2,"change-of-value" },
1109 {3,"command-failure" },
1110 {4,"floating-limit" },
1111 {5,"out-of-range" },
1112 {6,"complex-event-type" },
1113 {7,"buffer-ready" },
1114 {8,"change-of-life-safety" },
1116 {10,"buffer-ready" },
1117 {11,"unsigned-range" },
1119 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
1120 Enumerated values 64-65535 may be used by others subject to
1121 the procedures and constraints described in Clause 23.
1122 It is expected that these enumerated values will correspond
1123 to the use of the complex-event-type CHOICE [6] of the
1124 BACnetNotificationParameters production. */
1127 static const value_string
1128 BACnetEventState [] = {
1134 {5,"life-safety-alarm" },
1136 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
1137 Enumerated values 64-65535 may be used by others subject to
1138 the procedures and constraints described in Clause 23. */
1141 static const value_string
1142 BACnetLogStatus [] = {
1143 {0,"log-disabled" },
1144 {1,"buffer-purged" },
1148 static const value_string
1149 BACnetMaintenance [] = {
1151 {1,"periodic-test" },
1152 {2,"need-service-operational" },
1153 {3,"need-service-inoperative" },
1157 static const value_string
1158 BACnetNotifyType [] = {
1161 {2,"ack-notification" },
1165 static const value_string
1166 BACnetServicesSupported [] = {
1167 {0,"acknowledgeAlarm"},
1168 {1,"confirmedCOVNotification"},
1169 {2,"confirmedEventNotification"},
1170 {3,"getAlarmSummary"},
1171 {4,"getEnrollmentSummary"},
1173 {6,"atomicReadFile"},
1174 {7,"atomicWriteFile"},
1175 {8,"addListElement"},
1176 {9,"removeListElement"},
1177 {10,"createObject"},
1178 {11,"deleteObject"},
1179 {12,"readProperty"},
1180 {13,"readPropertyConditional"},
1181 {14,"readPropertyMultiple"},
1182 {15,"writeProperty"},
1183 {16,"writePropertyMultiple"},
1184 {17,"deviceCommunicationControl"},
1185 {18,"confirmedPrivateTransfer"},
1186 {19,"confirmedTextMessage"},
1187 {20,"reinitializeDevice"},
1191 {24,"authenticate"},
1195 {28,"unconfirmedCOVNotification"},
1196 {29,"unconfirmedEventNotification"},
1197 {30,"unconfirmedPrivateTransfer"},
1198 {31,"unconfirmedTextMessage"},
1199 {32,"timeSynchronization"},
1203 {36,"utcTimeSynchronization"},
1204 {37,"lifeSafetyOperation"},
1205 {38,"subscribeCOVProperty"},
1206 {39,"getEventInformation"},
1210 static const value_string
1211 BACnetPropertyStates [] = {
1212 {0,"boolean-value"},
1216 {4,"program-change"},
1217 {5,"program-state"},
1218 {6,"reason-for-halt"},
1221 {9,"system-status"},
1223 {11,"unsigned-value"},
1224 {12,"life-safety-mode"},
1225 {13,"life-safety-state"},
1226 {14,"door-alarm-state"},
1228 /* Tag values 0-63 are reserved for definition by ASHRAE.
1229 Tag values of 64-254 may be used by others to accommodate
1230 vendor specific properties that have discrete or enumerated values,
1231 subject to the constraints described in Clause 23. */
1234 static const value_string
1235 BACnetProgramError [] = {
1242 /* Enumerated values 0-63 are reserved for definition by ASHRAE.
1243 Enumerated values 64-65535 may be used by others subject to
1244 the procedures and constraints described in Clause 23. */
1247 static const value_string
1248 BACnetProgramRequest [] = {
1258 static const value_string
1259 BACnetProgramState [] = {
1269 static const value_string
1270 BACnetReinitializedStateOfDevice [] = {
1281 static const value_string
1282 BACnetPolarity [] = {
1288 static const value_string
1289 BACnetTagNames[] = {
1290 { 5, "Extended Value" },
1291 { 6, "Opening Tag" },
1292 { 7, "Closing Tag" },
1296 static const value_string
1297 BACnetReadRangeOptions[] = {
1298 { 3, "range byPosition" },
1299 { 4, "range byTime" },
1300 { 5, "range timeRange" },
1301 { 6, "range bySequenceNumber" },
1302 { 7, "range byTime" },
1306 /* Present_Value for Load Control Object */
1307 static const value_string
1308 BACnetShedState[] = {
1309 { 0, "shed-inactive" },
1310 { 1, "shed-request-pending" },
1311 { 2, "shed-compliant" },
1312 { 3, "shed-non-compliant" },
1316 static const value_string
1317 BACnetVendorIdentifiers [] = {
1320 { 2, "The Trane Company" },
1321 { 3, "McQuay International" },
1323 { 5, "Johnson Controls, Inc." },
1324 { 6, "American Auto-Matrix" },
1325 { 7, "Siemens Building Technologies, Ltd., Landis & Staefa Division Europe" },
1326 { 8, "Delta Controls" },
1327 { 9, "Siemens Building Technologies, Inc." },
1328 { 10, "Tour Andover Controls Corporation" },
1330 { 12, "Orion Analysis Corporation" },
1331 { 13, "Teletrol Systems Inc." },
1332 { 14, "Cimetrics Technology" },
1333 { 15, "Cornell University" },
1334 { 16, "United Technologies Carrier" },
1335 { 17, "Honeywell Inc." },
1336 { 18, "Alerton / Honeywell" },
1338 { 20, "Hewlett-Packard Company" },
1339 { 21, "Dorsette's Inc." },
1340 { 22, "Cerberus AG" },
1341 { 23, "York Controls Group" },
1342 { 24, "Automated Logic Corporation" },
1343 { 25, "CSI Control Systems International" },
1344 { 26, "Phoenix Controls Corporation" },
1345 { 27, "Innovex Technologies, Inc." },
1346 { 28, "KMC Controls, Inc." },
1347 { 29, "Xn Technologies, Inc." },
1348 { 30, "Hyundai Information Technology Co., Ltd." },
1349 { 31, "Tokimec Inc." },
1351 { 33, "North Communications Limited" },
1353 { 35, "Reliable Controls Corporation" },
1354 { 36, "Tridium Inc." },
1355 { 37, "Sierra Monitor Corp." },
1356 { 38, "Silicon Energy" },
1357 { 39, "Kieback & Peter GmbH & Co KG" },
1358 { 40, "Anacon Systems, Inc." },
1359 { 41, "Systems Controls & Instruments, LLC" },
1360 { 42, "Lithonia Lighting" },
1361 { 43, "Micropower Manufacturing" },
1362 { 44, "Matrix Controls" },
1363 { 45, "METALAIRE" },
1364 { 46, "ESS Engineering" },
1365 { 47, "Sphere Systems Pty Ltd." },
1366 { 48, "Walker Technologies Corporation" },
1367 { 49, "H I Solutions, Inc." },
1369 { 51, "SAMSON AG" },
1370 { 52, "Badger Meter Inc." },
1371 { 53, "DAIKIN Industries Ltd." },
1372 { 54, "NARA Controls Inc." },
1373 { 55, "Mammoth Inc." },
1374 { 56, "Liebert Corporation" },
1375 { 57, "SEMCO Incorporated" },
1376 { 58, "Air Monitor Corporation" },
1377 { 59, "TRIATEK, Inc." },
1379 { 61, "Multistack" },
1380 { 62, "TSI Incorporated" },
1381 { 63, "Weather-Rite, Inc." },
1382 { 64, "Dunham-Bush" },
1383 { 65, "Reliance Electric" },
1385 { 67, "Regulator Australia PTY Ltd." },
1386 { 68, "Touch-Plate Lighting Controls" },
1387 { 69, "Amann GmbH" },
1388 { 70, "RLE Technologies" },
1389 { 71, "Cardkey Systems" },
1390 { 72, "SECOM Co., Ltd." },
1391 { 73, "ABB Gebaudetechnik AG Bereich NetServ" },
1392 { 74, "KNX Association cvba" },
1393 { 75, "Institute of Electrical Installation Engineers of Japan (IEIEJ)" },
1394 { 76, "Nohmi Bosai, Ltd." },
1395 { 77, "Carel S.p.A." },
1396 { 78, "AirSense Technology, Inc." },
1397 { 79, "Hochiki Corporation" },
1398 { 80, "Fr. Sauter AG" },
1399 { 81, "Matsushita Electric Works, Ltd." },
1400 { 82, "Mitsubishi Electric Corporation, Inazawa Works" },
1401 { 83, "Mitsubishi Heavy Industries, Ltd." },
1402 { 84, "ITT Bell & Gossett" },
1403 { 85, "Yamatake Building Systems Co., Ltd." },
1404 { 86, "The Watt Stopper, Inc." },
1405 { 87, "Aichi Tokei Denki Co., Ltd." },
1406 { 88, "Activation Technologies, LLC" },
1407 { 89, "Saia-Burgess Controls, Ltd." },
1408 { 90, "Hitachi, Ltd." },
1409 { 91, "Novar Corp./Trend Control Systems Ltd." },
1410 { 92, "Mitsubishi Electric Lighting Corporation" },
1411 { 93, "Argus Control Systems, Ltd." },
1412 { 94, "Kyuki Corporation" },
1413 { 95, "Richards-Zeta Building Intelligence, Inc." },
1414 { 96, "Scientech R&D, Inc." },
1415 { 97, "VCI Controls, Inc." },
1416 { 98, "Toshiba Corporation" },
1417 { 99, "Mitsubishi Electric Corporation Air Conditioning & Refrigeration Systems Works" },
1418 { 100, "Custom Mechanical Equipment, LLC" },
1419 { 101, "ClimateMaster" },
1420 { 102, "ICP Panel-Tec, Inc." },
1421 { 103, "D-Tek Controls" },
1422 { 104, "NEC Engineering, Ltd." },
1423 { 105, "PRIVA BV" },
1424 { 106, "Meidensha Corporation" },
1425 { 107, "JCI Systems Integration Services" },
1426 { 108, "Freedom Corporation" },
1427 { 109, "Neuberger Gebaudeautomation GmbH" },
1428 { 110, "Sitronix" },
1429 { 111, "Leviton Manufacturing" },
1430 { 112, "Fujitsu Limited" },
1431 { 113, "Emerson Network Power" },
1432 { 114, "S. A. Armstrong, Ltd." },
1433 { 115, "Visonet AG" },
1434 { 116, "M&M Systems, Inc." },
1435 { 117, "Custom Software Engineering" },
1436 { 118, "Nittan Company, Limited" },
1437 { 119, "Elutions Inc. (Wizcon Systems SAS)" },
1438 { 120, "Pacom Systems Pty., Ltd." },
1439 { 121, "Unico, Inc." },
1440 { 122, "Ebtron, Inc." },
1441 { 123, "Scada Engine" },
1442 { 124, "AC Technology Corporation" },
1443 { 125, "Eagle Technology" },
1444 { 126, "Data Aire, Inc." },
1445 { 127, "ABB, Inc." },
1446 { 128, "Transbit Sp. z o. o." },
1447 { 129, "Toshiba Carrier Corporation" },
1448 { 130, "Shenzhen Junzhi Hi-Tech Co., Ltd." },
1449 { 131, "Tokai Soft" },
1451 { 133, "Veris Industries" },
1452 { 134, "Centaurus Prime" },
1453 { 135, "Sand Network Systems" },
1454 { 136, "Regulvar, Inc." },
1455 { 137, "Fastek International, Ltd." },
1456 { 138, "PowerCold Comfort Air Solutions, Inc." },
1457 { 139, "I Controls" },
1458 { 140, "Viconics Electronics, Inc." },
1459 { 141, "Yaskawa Electric America, Inc." },
1460 { 142, "Plueth Regelsysteme" },
1461 { 143, "Digitale Mess- und Steuersysteme AG" },
1462 { 144, "Fujitsu General Limited" },
1463 { 145, "Project Engineering S.r.l." },
1464 { 146, "Sanyo Electric Co., Ltd." },
1465 { 147, "Integrated Information Systems, Inc." },
1466 { 148, "Temco Controls, Ltd." },
1467 { 149, "Airtek Technologies, Inc." },
1468 { 150, "Advantech Corporation" },
1469 { 151, "Titan Products, Ltd." },
1470 { 152, "Regel Partners" },
1471 { 153, "National Environmental Product" },
1472 { 154, "Unitec Corporation" },
1473 { 155, "Kanden Engineering Company" },
1474 { 156, "Messner Gebaudetechnik GmbH" },
1475 { 157, "Integrated.CH" },
1476 { 158, "EH Price Limited" },
1477 { 159, "SE-Elektronic GmbH" },
1478 { 160, "Rockwell Automation" },
1479 { 161, "Enflex Corp." },
1480 { 162, "ASI Controls" },
1481 { 163, "SysMik GmbH Dresden" },
1482 { 164, "HSC Regelungstechnik GmbH" },
1483 { 165, "Smart Temp Australia Pty. Ltd." },
1484 { 166, "PCI Lighting Control Systems" },
1485 { 167, "Duksan Mecasys Co., Ltd." },
1486 { 168, "Fuji IT Co., Ltd." },
1487 { 169, "Vacon Plc" },
1488 { 170, "Leader Controls" },
1489 { 171, "Cylon Controls, Ltd." },
1491 { 173, "Mitsubishi Electric Building Techno-Service Co., Ltd." },
1492 { 174, "Building Control Integrators" },
1493 { 175, "ITG Worldwide (M) Sdn Bhd" },
1494 { 176, "Lutron Electronics Co., Inc." },
1495 { 177, "Cooper-Atkins Corporation" },
1496 { 178, "LOYTEC Electronics GmbH" },
1498 { 180, "Mega Controls Limited" },
1499 { 181, "Micro Control Systems, Inc." },
1500 { 182, "Kiyon, Inc." },
1501 { 183, "Dust Networks" },
1502 { 184, "Advanced Building Automation Systems" },
1503 { 185, "Hermos AG" },
1506 { 188, "Lynxspring" },
1507 { 189, "Schneider Toshiba Inverter Europe" },
1508 { 190, "Danfoss Drives A/S" },
1509 { 191, "Eaton Corporation" },
1510 { 192, "Matyca S.A." },
1511 { 193, "Botech AB" },
1512 { 194, "Noveo, Inc." },
1514 { 196, "Yokogawa Electric Corporation" },
1515 { 197, "GFR Gesellschaft fur Regelungstechnik" },
1516 { 198, "Exact Logic" },
1517 { 199, "Mass Electronics Pty Ltd dba Innotech Control Systems Australia" },
1518 { 200, "Kandenko Co., Ltd." },
1519 { 201, "DTF, Daten-Technik Fries" },
1520 { 202, "Klimasoft, Ltd." },
1521 { 203, "Toshiba Schneider Inverter Corporation" },
1522 { 204, "Control Applications, Ltd." },
1523 { 205, "KDT Systems Co., Ltd." },
1524 { 206, "Onicon Incorporated" },
1525 { 207, "Automation Displays, Inc." },
1526 { 208, "Control Solutions, Inc." },
1527 { 209, "Remsdaq Limited" },
1528 { 210, "NTT Facilities, Inc." },
1529 { 211, "VIPA GmbH" },
1530 { 212, "TSC21 Association of Japan" },
1531 { 213, "BBP Energie Ltee" },
1532 { 214, "HRW Limited" },
1533 { 215, "Lighting Control & Design, Inc." },
1534 { 216, "Mercy Electronic and Electrical Industries" },
1535 { 217, "Samsung SDS Co., Ltd" },
1536 { 218, "Impact Facility Solutions, Inc." },
1537 { 219, "Aircuity" },
1538 { 220, "Control Techniques, Ltd." },
1539 { 221, "Evolve Control Systems, LLC" },
1540 { 222, "WAGO Kontakttechnik GmbH & Co. KG" },
1541 { 223, "Cerus Industrial" },
1542 { 224, "Chloride Power Protection Company" },
1543 { 225, "Computrols, Inc." },
1544 { 226, "Phoenix Contact GmbH & Co. KG" },
1545 { 227, "Grundfos Management A/S" },
1546 { 228, "Ridder Drive Systems" },
1547 { 229, "Soft Device SDN BHD" },
1548 { 230, "Integrated Control Technology Limited" },
1549 { 231, "AIRxpert Systems, Inc." },
1550 { 232, "Microtrol Limited" },
1551 { 233, "Red Lion Controls" },
1552 { 234, "Digital Electronics Corporation" },
1553 { 235, "Ennovatis GmbH" },
1554 { 236, "Serotonin Software Technologies, Inc." },
1555 { 237, "LS Industrial Systems Co., Ltd." },
1556 { 238, "Square D Company" },
1557 { 239, "S Squared Innovations, Inc." },
1558 { 240, "Aricent Ltd." },
1559 { 241, "EtherMetrics, LLC" },
1560 { 242, "Industrial Control Communications, Inc." },
1561 { 243, "Paragon Controls, Inc." },
1562 { 244, "A. O. Smith Corporation" },
1563 { 245, "Contemporary Control Systems, Inc." },
1564 { 246, "Intesis Software SL" },
1565 { 247, "Ingenieurgesellschaft N. Hartleb mbH" },
1566 { 248, "Heat-Timer Corporation" },
1567 { 249, "Ingrasys Technology, Inc." },
1568 { 250, "Costerm Building Automation" },
1570 { 252, "Embedia Technologies Corp." },
1571 { 253, "Technilog" },
1572 { 254, "HR Controls Ltd. & Co. KG" },
1573 { 255, "Lennox International, Inc." },
1574 { 256, "RK-Tec Rauchklappen-Steuerungssysteme GmbH & Co. KG" },
1575 { 257, "Thermomax, Ltd." },
1576 { 258, "ELCON Electronic Control, Ltd." },
1577 { 259, "Larmia Control AB" },
1578 { 260, "BACnet Stack at SourceForge" },
1579 { 261, "G4S Security Services A/S" },
1580 { 262, "Sitek S.p.A." },
1581 { 263, "Cristal Controles" },
1582 { 264, "Regin AB" },
1583 { 265, "Dimension Software, Inc. " },
1584 { 266, "SynapSense Corporation" },
1585 { 267, "Beijing Nantree Electronic Co., Ltd." },
1586 { 268, "Camus Hydronics Ltd." },
1587 { 269, "Kawasaki Heavy Industries, Ltd. " },
1588 { 270, "Critical Environment Technologies" },
1589 { 271, "ILSHIN IBS Co., Ltd." },
1590 { 272, "ELESTA Energy Control AG" },
1591 { 273, "KROPMAN Installatietechniek" },
1592 { 274, "Baldor Electric Company" },
1593 { 275, "INGA mbH" },
1594 { 276, "GE Consumer & Industrial" },
1595 { 277, "Functional Devices, Inc." },
1597 { 279, "M-System Co., Ltd." },
1598 { 280, "Yokota Co., Ltd." },
1599 { 281, "Hitranse Technology Co., LTD" },
1600 { 282, "Federspiel Controls" },
1601 { 283, "Kele, Inc." },
1602 { 284, "Opera Electronics, Inc." },
1604 { 286, "Embedded Science Labs, LLC" },
1605 { 287, "Parker Hannifin Corporation" },
1606 { 288, "MaCaPS International Limited" },
1607 { 289, "Link4 Corporation" },
1608 { 290, "Romutec Steuer-u. Regelsysteme GmbH" },
1609 { 291, "Pribusin, Inc." },
1610 { 292, "Advantage Controls" },
1611 { 293, "Critical Room Control" },
1613 { 295, "Tongdy Control Technology Co., Ltd." },
1614 { 296, "ISSARO Integrierte Systemtechnik" },
1615 { 297, "Pro-Dev Industries" },
1616 { 298, "DRI-STEEM" },
1617 { 299, "Creative Electronic GmbH" },
1618 { 300, "Swegon AB" },
1619 { 301, "Jan Brachacek" },
1620 { 302, "Hitachi Appliances, Inc." },
1621 { 303, "Real Time Automation, Inc." },
1622 { 304, "ITEC Hankyu-Hanshin Co." },
1623 { 305, "Cyrus E&M Engineering Co., Ltd." },
1624 { 306, "Racine Federated, Inc." },
1625 { 307, "Verari Systems, Inc." },
1626 { 308, "Elesta GmbH Building Automation" },
1627 { 309, "Securiton" },
1628 { 310, "OSlsoft, Inc." },
1629 { 311, "Hanazeder Electronic GmbH" },
1630 { 312, "Honeywell Security Deutschland, Novar GmbH" },
1631 { 313, "Siemens Energy & Automation, Inc." },
1632 { 314, "ETM Professional Control GmbH" },
1633 { 315, "Meitav-tec, Ltd." },
1634 { 316, "Janitza Electronics GmbH" },
1635 { 317, "MKS Nordhausen" },
1636 { 318, "De Gier Drive Systems B.V." },
1637 { 319, "Cypress Envirosystems" },
1638 { 320, "SMARTron s.r.o." },
1639 { 321, "Verari Systems, Inc." },
1640 { 322, "K-W Electronic Service, Inc." },
1641 { 323, "ALFA-SMART Energy Management" },
1642 { 324, "Telkonet, Inc." },
1643 { 325, "Securiton GmbH" },
1644 { 326, "Cemtrex, Inc." },
1645 { 327, "Performance Technologies, Inc." },
1646 { 328, "Xtralis (Aust) Pty Ltd" },
1647 { 329, "TROX GmbH" },
1648 { 330, "Beijing Hysine Technology Co., Ltd" },
1649 { 331, "RCK Controls, Inc." },
1651 { 333, "Novar/Honeywell" },
1652 { 334, "The S4 Group, Inc." },
1653 { 335, "Schneider Electric" },
1654 { 336, "LHA Systems" },
1655 { 337, "GHM engineering Group, Inc." },
1656 { 338, "Cllimalux S.A." },
1657 { 339, "VAISALA Oyj" },
1658 { 340, "COMPLEX (Beijing) Technology, Co., LTD." },
1659 { 342, "POWERPEG NSI Limited" },
1660 { 343, "BACnet Interoperability Testing Services, Inc." },
1661 { 344, "Teco a.s." },
1665 static int proto_bacapp = -1;
1666 static int hf_bacapp_type = -1;
1667 static int hf_bacapp_pduflags = -1;
1668 static int hf_bacapp_SEG = -1;
1669 static int hf_bacapp_MOR = -1;
1670 static int hf_bacapp_SA = -1;
1671 static int hf_bacapp_response_segments = -1;
1672 static int hf_bacapp_max_adpu_size = -1;
1673 static int hf_bacapp_invoke_id = -1;
1674 static int hf_bacapp_objectType = -1;
1675 static int hf_bacapp_instanceNumber = -1;
1676 static int hf_bacapp_sequence_number = -1;
1677 static int hf_bacapp_window_size = -1;
1678 static int hf_bacapp_service = -1;
1679 static int hf_bacapp_NAK = -1;
1680 static int hf_bacapp_SRV = -1;
1681 static int hf_BACnetRejectReason = -1;
1682 static int hf_BACnetAbortReason = -1;
1683 static int hf_BACnetApplicationTagNumber = -1;
1684 static int hf_BACnetContextTagNumber = -1;
1685 static int hf_BACnetExtendedTagNumber = -1;
1686 static int hf_BACnetNamedTag = -1;
1687 static int hf_BACnetTagClass = -1;
1688 static int hf_BACnetCharacterSet = -1;
1689 static int hf_bacapp_tag = -1;
1690 static int hf_bacapp_tag_lvt = -1;
1691 static int hf_bacapp_tag_value8 = -1;
1692 static int hf_bacapp_tag_value16 = -1;
1693 static int hf_bacapp_tag_value32 = -1;
1694 static int hf_bacapp_tag_ProcessId = -1;
1695 static int hf_bacapp_tag_initiatingObjectType = -1;
1696 static int hf_bacapp_vpart = -1;
1697 static int hf_bacapp_uservice = -1;
1698 static int hf_BACnetPropertyIdentifier = -1;
1699 static int hf_BACnetVendorIdentifier = -1;
1702 static gint ett_bacapp = -1;
1703 static gint ett_bacapp_control = -1;
1704 static gint ett_bacapp_tag = -1;
1705 static gint ett_bacapp_list = -1;
1706 static gint ett_bacapp_value = -1;
1708 static dissector_handle_t data_handle;
1709 static gint32 propertyIdentifier = -1;
1710 static gint32 propertyArrayIndex = -1;
1711 static guint32 object_type = 4096;
1713 static guint8 bacapp_flags = 0;
1714 static guint8 bacapp_seq = 0;
1716 /* Used when there are ranges of reserved and proprietary enumerations */
1718 val_to_split_str(guint32 val, guint32 split_val, const value_string *vs,
1719 const char *fmt, const char *split_fmt)
1721 if (val < split_val)
1722 return val_to_str(val, vs, fmt);
1724 return val_to_str(val, vs, split_fmt);
1727 /* from clause 20.2.1.3.2 Constructed Data */
1728 /* returns true if the extended value is used */
1729 static gboolean tag_is_extended_value(guint8 tag)
1731 return (tag & 0x07) == 5;
1734 static gboolean tag_is_opening(guint8 tag)
1736 return (tag & 0x07) == 6;
1739 static gboolean tag_is_closing(guint8 tag)
1741 return (tag & 0x07) == 7;
1744 /* from clause 20.2.1.1 Class
1745 class bit shall be one for context specific tags */
1746 /* returns true if the tag is context specific */
1747 static gboolean tag_is_context_specific(guint8 tag)
1749 return (tag & 0x08) != 0;
1752 static gboolean tag_is_extended_tag_number(guint8 tag)
1754 return ((tag & 0xF0) == 0xF0);
1757 static guint32 object_id_type(guint32 object_identifier)
1759 return ((object_identifier >> 22) & 0x3FF);
1762 static guint32 object_id_instance(guint32 object_identifier)
1764 return (object_identifier & 0x3FFFFF);
1768 fTagNo (tvbuff_t *tvb, guint offset)
1770 return (guint)(tvb_get_guint8(tvb, offset) >> 4);
1774 fUnsigned32 (tvbuff_t *tvb, guint offset, guint32 lvt, guint32 *val)
1776 gboolean valid = TRUE;
1780 *val = tvb_get_guint8(tvb, offset);
1783 *val = tvb_get_ntohs(tvb, offset);
1786 *val = tvb_get_ntoh24(tvb, offset);
1789 *val = tvb_get_ntohl(tvb, offset);
1800 fUnsigned64 (tvbuff_t *tvb, guint offset, guint32 lvt, guint64 *val)
1802 gboolean valid = FALSE;
1806 if (lvt && (lvt <= 8)) {
1808 data = tvb_get_guint8(tvb, offset);
1809 for (i = 0; i < lvt; i++) {
1810 data = tvb_get_guint8(tvb, offset+i);
1811 value = (value << 8) + data;
1819 /* BACnet Signed Value uses 2's compliment notation, but with a twist:
1820 All signed integers shall be encoded in the smallest number of octets
1821 possible. That is, the first octet of any multi-octet encoded value
1822 shall not be X'00' if the most significant bit (bit 7) of the second
1823 octet is 0, and the first octet shall not be X'FF' if the most
1824 significant bit of the second octet is 1. ASHRAE-135-2004-20.2.5 */
1826 fSigned64 (tvbuff_t *tvb, guint offset, guint32 lvt, gint64 *val)
1828 gboolean valid = FALSE;
1832 /* we can only handle 7 bytes for a 64-bit value due to signed-ness */
1833 if (lvt && (lvt <= 7)) {
1835 data = tvb_get_guint8(tvb, offset);
1836 if ((data & 0x80) != 0)
1837 value = (-1 << 8) | data;
1840 for (i = 1; i < lvt; i++) {
1841 data = tvb_get_guint8(tvb, offset+i);
1842 value = (value << 8) + data;
1851 fTagHeaderTree (tvbuff_t *tvb, proto_tree *tree, guint offset,
1852 guint8 *tag_no, guint8* tag_info, guint32 *lvt)
1857 guint lvt_len = 1; /* used for tree display of lvt */
1858 guint lvt_offset; /* used for tree display of lvt */
1860 proto_tree *subtree;
1862 lvt_offset = offset;
1863 tag = tvb_get_guint8(tvb, offset);
1866 /* To solve the problem of lvt values of 6/7 being indeterminate - it */
1867 /* can mean open/close tag or length of 6/7 after the length is */
1868 /* computed below - store whole tag info, not just context bit. */
1869 if (tag_is_context_specific(tag)) *tag_info = tag & 0x0F;
1871 if (tag_is_extended_tag_number(tag)) {
1872 *tag_no = tvb_get_guint8(tvb, offset + tag_len++);
1874 if (tag_is_extended_value(tag)) { /* length is more than 4 Bytes */
1875 lvt_offset += tag_len;
1876 value = tvb_get_guint8(tvb, lvt_offset);
1878 if (value == 254) { /* length is encoded with 16 Bits */
1879 *lvt = tvb_get_ntohs(tvb, lvt_offset+1);
1882 } else if (value == 255) { /* length is encoded with 32 Bits */
1883 *lvt = tvb_get_ntohl(tvb, lvt_offset+1);
1891 if (tag_is_closing(tag) || tag_is_opening(tag))
1892 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
1893 "%s: %u", val_to_str(
1894 tag & 0x07, BACnetTagNames, "Unknown (%d)"),
1896 else if (tag_is_context_specific(tag)) {
1897 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
1898 "Context Tag: %u, Length/Value/Type: %u",
1901 ti = proto_tree_add_text(tree, tvb, offset, tag_len,
1902 "Application Tag: %s, Length/Value/Type: %u",
1904 BACnetApplicationTagNumber,
1905 ASHRAE_Reserved_Fmt),
1907 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
1908 /* details if needed */
1909 proto_tree_add_item(subtree, hf_BACnetTagClass, tvb, offset, 1, FALSE);
1910 if (tag_is_extended_tag_number(tag)) {
1911 proto_tree_add_uint_format(subtree,
1912 hf_BACnetContextTagNumber,
1913 tvb, offset, 1, tag,
1914 "Extended Tag Number");
1915 proto_tree_add_item(subtree,
1916 hf_BACnetExtendedTagNumber,
1917 tvb, offset + 1, 1, FALSE);
1919 if (tag_is_context_specific(tag))
1920 proto_tree_add_item(subtree,
1921 hf_BACnetContextTagNumber,
1922 tvb, offset, 1, FALSE);
1924 proto_tree_add_item(subtree,
1925 hf_BACnetApplicationTagNumber,
1926 tvb, offset, 1, FALSE);
1928 if (tag_is_closing(tag) || tag_is_opening(tag))
1929 proto_tree_add_item(subtree,
1931 tvb, offset, 1, FALSE);
1932 else if (tag_is_extended_value(tag)) {
1933 proto_tree_add_item(subtree,
1935 tvb, offset, 1, FALSE);
1936 proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
1937 tvb, lvt_offset, lvt_len, *lvt);
1939 proto_tree_add_uint(subtree, hf_bacapp_tag_lvt,
1940 tvb, lvt_offset, lvt_len, *lvt);
1947 fTagHeader (tvbuff_t *tvb, guint offset, guint8 *tag_no, guint8* tag_info,
1950 return fTagHeaderTree (tvb, NULL, offset, tag_no, tag_info, lvt);
1954 fNullTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
1956 guint8 tag_no, tag_info;
1959 proto_tree *subtree;
1961 ti = proto_tree_add_text(tree, tvb, offset, 1, "%sNULL", label);
1962 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
1963 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
1969 fBooleanTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
1971 guint8 tag_no, tag_info;
1975 proto_tree *subtree;
1978 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
1979 if (tag_info && lvt == 1)
1981 lvt = tvb_get_guint8(tvb, offset+1);
1985 ti = proto_tree_add_text(tree, tvb, offset, bool_len,
1986 "%s%s", label, lvt == 0 ? "FALSE" : "TRUE");
1987 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
1988 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
1990 return offset + bool_len;
1994 fUnsignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
1997 guint8 tag_no, tag_info;
2001 proto_tree *subtree;
2003 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
2004 /* only support up to an 8 byte (64-bit) integer */
2005 if (fUnsigned64 (tvb, offset + tag_len, lvt, &val))
2006 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
2007 "%s(Unsigned) %" G_GINT64_MODIFIER "u", label, val);
2009 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
2010 "%s - %u octets (Unsigned)", label, lvt);
2011 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
2012 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
2014 return offset+tag_len+lvt;
2017 /* set split_val to zero when not needed */
2019 fEnumeratedTagSplit (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
2020 const value_string *vs, guint32 split_val)
2023 guint8 tag_no, tag_info;
2027 proto_tree *subtree;
2029 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
2030 /* only support up to a 4 byte (32-bit) enumeration */
2031 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val)) {
2033 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
2034 "%s %s", label, val_to_split_str(val, split_val, vs,
2035 ASHRAE_Reserved_Fmt,Vendor_Proprietary_Fmt));
2037 ti =proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
2038 "%s %u", label, val);
2040 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
2041 "%s - %u octets (enumeration)", label, lvt);
2043 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
2044 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
2046 return offset+tag_len+lvt;
2050 fEnumeratedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
2051 const value_string *vs)
2053 return fEnumeratedTagSplit (tvb, tree, offset, label, vs, 0);
2057 fSignedTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
2060 guint8 tag_no, tag_info;
2064 proto_tree *subtree;
2066 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
2067 if (fSigned64 (tvb, offset + tag_len, lvt, &val))
2068 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
2069 "%s(Signed) %" G_GINT64_MODIFIER "d", label, val);
2071 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
2072 "%s - %u octets (Signed)", label, lvt);
2073 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
2074 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
2076 return offset+tag_len+lvt;
2080 fRealTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
2082 guint8 tag_no, tag_info;
2087 proto_tree *subtree;
2089 tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
2090 f_val = tvb_get_ntohieee_float(tvb, offset+tag_len);
2091 ti = proto_tree_add_text(tree, tvb, offset, 4+tag_len,
2092 "%s%f (Real)", label, f_val);
2093 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
2094 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
2096 return offset+tag_len+4;
2100 fDoubleTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
2102 guint8 tag_no, tag_info;
2107 proto_tree *subtree;
2109 tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
2110 d_val = tvb_get_ntohieee_double(tvb, offset+tag_len);
2111 ti = proto_tree_add_text(tree, tvb, offset, 8+tag_len,
2112 "%s%lf (Double)", label, d_val);
2113 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
2114 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
2116 return offset+tag_len+8;
2120 fProcessId (tvbuff_t *tvb, proto_tree *tree, guint offset)
2122 guint32 val = 0, lvt;
2123 guint8 tag_no, tag_info;
2125 proto_tree *subtree;
2128 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
2129 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val))
2130 ti = proto_tree_add_uint(tree, hf_bacapp_tag_ProcessId,
2131 tvb, offset, lvt+tag_len, val);
2133 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
2134 "Process Identifier - %u octets (Signed)", lvt);
2135 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
2136 offset += tag_len + lvt;
2142 fTimeSpan (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
2144 guint32 val = 0, lvt;
2145 guint8 tag_no, tag_info;
2147 proto_tree *subtree;
2150 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
2151 if (fUnsigned32 (tvb, offset+tag_len, lvt, &val))
2152 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
2153 "%s (hh.mm.ss): %d.%02d.%02d%s",
2155 (val / 3600), ((val % 3600) / 60), (val % 60),
2156 val == 0 ? " (indefinite)" : "");
2158 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
2159 "%s - %u octets (Signed)", label, lvt);
2160 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
2161 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
2163 return offset+tag_len+lvt;
2167 fWeekNDay (tvbuff_t *tvb, proto_tree *tree, guint offset)
2169 guint32 month, weekOfMonth, dayOfWeek;
2170 guint8 tag_no, tag_info;
2174 proto_tree *subtree;
2176 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
2177 month = tvb_get_guint8(tvb, offset+tag_len);
2178 weekOfMonth = tvb_get_guint8(tvb, offset+tag_len+1);
2179 dayOfWeek = tvb_get_guint8(tvb, offset+tag_len+2);
2180 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s %s, %s",
2181 val_to_str(month, months, "month (%d) not found"),
2182 val_to_str(weekOfMonth, weekofmonth, "week of month (%d) not found"),
2183 val_to_str(dayOfWeek, day_of_week, "day of week (%d) not found"));
2184 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
2185 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
2187 return offset+tag_len+lvt;
2191 fDate (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
2193 guint32 year, month, day, weekday;
2194 guint8 tag_no, tag_info;
2198 proto_tree *subtree;
2200 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
2201 year = tvb_get_guint8(tvb, offset+tag_len);
2202 month = tvb_get_guint8(tvb, offset+tag_len+1);
2203 day = tvb_get_guint8(tvb, offset+tag_len+2);
2204 weekday = tvb_get_guint8(tvb, offset+tag_len+3);
2205 if ((year == 255) && (day == 255) && (month == 255) && (weekday == 255))
2207 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
2210 else if (year != 255)
2213 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
2214 "%s%s %d, %d, (Day of Week = %s)",
2215 label, val_to_str(month,
2217 "month (%d) not found"),
2218 day, year, val_to_str(weekday,
2224 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
2225 "%s%s %d, any year, (Day of Week = %s)",
2226 label, val_to_str(month, months, "month (%d) not found"),
2227 day, val_to_str(weekday, day_of_week, "(%d) not found"));
2229 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
2230 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
2232 return offset+tag_len+lvt;
2236 fTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
2238 guint32 hour, minute, second, msec, lvt;
2239 guint8 tag_no, tag_info;
2242 proto_tree *subtree;
2244 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
2245 hour = tvb_get_guint8(tvb, offset+tag_len);
2246 minute = tvb_get_guint8(tvb, offset+tag_len+1);
2247 second = tvb_get_guint8(tvb, offset+tag_len+2);
2248 msec = tvb_get_guint8(tvb, offset+tag_len+3);
2249 if ((hour == 255) && (minute == 255) && (second == 255) && (msec == 255))
2250 ti = proto_tree_add_text(tree, tvb, offset,
2251 lvt+tag_len, "%sany", label);
2253 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
2254 "%s%d:%02d:%02d.%d %s = %02d:%02d:%02d.%d",
2256 hour > 12 ? hour - 12 : hour,
2257 minute, second, msec,
2258 hour >= 12 ? "P.M." : "A.M.",
2259 hour, minute, second, msec);
2260 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
2261 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
2263 return offset+tag_len+lvt;
2267 fDateTime (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
2269 proto_tree *subtree = tree;
2272 if (label != NULL) {
2273 tt = proto_tree_add_text (subtree, tvb, offset, 1, "%s", label);
2274 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
2276 offset = fDate (tvb,subtree,offset,"Date: ");
2277 return fTime (tvb,subtree,offset,"Time: ");
2281 fTimeValue (tvbuff_t *tvb, proto_tree *tree, guint offset)
2283 guint lastoffset = 0;
2284 guint8 tag_no, tag_info;
2287 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
2288 lastoffset = offset;
2289 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
2290 if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
2293 offset = fTime (tvb,tree,offset,"Time: ");
2294 offset = fApplicationTypes(tvb, tree, offset, "Value: ");
2300 fCalendaryEntry (tvbuff_t *tvb, proto_tree *tree, guint offset)
2302 guint8 tag_no, tag_info;
2305 switch (fTagNo(tvb, offset)) {
2307 offset = fDate (tvb, tree, offset, "Date: ");
2309 case 1: /* dateRange */
2310 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
2311 offset = fDateRange (tvb, tree, offset);
2312 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
2314 case 2: /* BACnetWeekNDay */
2315 offset = fWeekNDay (tvb, tree, offset);
2324 static guint fTimeStamp (tvbuff_t *tvb, proto_tree *tree,
2325 guint offset, const gchar *label)
2327 guint8 tag_no = 0, tag_info = 0;
2330 if (tvb_length_remaining(tvb, offset) > 0) { /* don't loop, it's a CHOICE */
2331 switch (fTagNo(tvb, offset)) {
2333 offset = fTime (tvb, tree, offset, label?label:"timestamp: ");
2335 case 1: /* sequenceNumber */
2336 offset = fUnsignedTag (tvb, tree, offset,
2337 label?label:"sequence Number: ");
2339 case 2: /* dateTime */
2340 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
2341 offset = fDateTime (tvb, tree, offset, label?label:"timestamp: ");
2342 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
2354 fSetpointReference (tvbuff_t *tvb, proto_tree *tree, guint offset)
2356 guint lastoffset = 0;
2358 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
2359 lastoffset = offset;
2361 switch (fTagNo(tvb, offset)) {
2362 case 0: /* setpointReference */
2363 offset = fBACnetObjectPropertyReference (tvb,tree,offset);
2376 fClientCOV (tvbuff_t *tvb, proto_tree *tree, guint offset)
2378 if (tvb_length_remaining(tvb, offset) > 0) {
2379 offset = fApplicationTypes(tvb,tree,offset, "increment: ");
2384 static const value_string
2385 BACnetDaysOfWeek [] = {
2397 fDestination (tvbuff_t *tvb, proto_tree *tree, guint offset)
2399 if (tvb_length_remaining(tvb, offset) > 0) {
2400 offset = fApplicationTypesEnumerated(tvb,tree,offset,
2401 "valid Days: ", BACnetDaysOfWeek);
2402 offset = fTime (tvb,tree,offset,"from time: ");
2403 offset = fTime (tvb,tree,offset,"to time: ");
2404 offset = fRecipient (tvb,tree,offset);
2405 offset = fProcessId (tvb,tree,offset);
2406 offset = fApplicationTypes (tvb,tree,offset,
2407 "issue confirmed notifications: ");
2408 offset = fBitStringTagVS (tvb,tree,offset,
2409 "transitions: ", BACnetEventTransitionBits);
2417 fOctetString (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label, guint32 lvt)
2420 guint start = offset;
2421 guint8 tag_no, tag_info;
2422 proto_tree* subtree = tree;
2425 offset += fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
2429 tmp = tvb_bytes_to_str(tvb, offset, lvt);
2430 ti = proto_tree_add_text(tree, tvb, offset, lvt, "%s %s", label, tmp);
2435 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
2437 fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
2443 fAddress (tvbuff_t *tvb, proto_tree *tree, guint offset)
2445 guint8 tag_no, tag_info;
2449 offset = fUnsignedTag (tvb, tree, offset, "network-number");
2450 offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
2452 proto_tree_add_text(tree, tvb, offset, offs, "mac-address: broadcast");
2455 offset = fOctetString (tvb, tree, offset, "mac-address: ", lvt);
2461 fSessionKey (tvbuff_t *tvb, proto_tree *tree, guint offset)
2463 offset = fOctetString (tvb,tree,offset,"session key: ", 8);
2464 return fAddress (tvb,tree,offset);
2468 fObjectIdentifier (tvbuff_t *tvb, proto_tree *tree, guint offset)
2470 guint8 tag_no, tag_info;
2474 proto_tree *subtree;
2477 tag_length = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
2478 object_id = tvb_get_ntohl(tvb,offset+tag_length);
2479 object_type = object_id_type(object_id);
2480 ti = proto_tree_add_text(tree, tvb, offset, tag_length + 4,
2481 "ObjectIdentifier: %s, %u",
2482 val_to_split_str(object_type,
2485 ASHRAE_Reserved_Fmt,
2486 Vendor_Proprietary_Fmt),
2487 object_id_instance(object_id));
2488 /* here are the details of how we arrived at the above text */
2489 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
2490 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
2491 offset += tag_length;
2492 proto_tree_add_item(subtree, hf_bacapp_objectType, tvb, offset, 4, FALSE);
2493 proto_tree_add_item(subtree, hf_bacapp_instanceNumber, tvb, offset, 4, FALSE);
2500 fRecipient (tvbuff_t *tvb, proto_tree *tree, guint offset)
2502 guint8 tag_no, tag_info;
2505 fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
2507 if (tag_no == 0) { /* device */
2508 offset = fObjectIdentifier (tvb, tree, offset);
2510 else { /* address */
2511 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
2512 offset = fAddress (tvb, tree, offset);
2513 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
2520 fRecipientProcess (tvbuff_t *tvb, proto_tree *tree, guint offset)
2522 guint lastoffset = 0;
2523 guint8 tag_no, tag_info;
2526 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
2527 lastoffset = offset;
2529 switch (fTagNo(tvb, offset)) {
2530 case 0: /* recipient */
2531 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
2532 offset = fRecipient (tvb, tree, offset);
2533 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
2535 case 1: /* processId */
2536 offset = fProcessId (tvb, tree, offset);
2537 lastoffset = offset;
2547 fAddressBinding (tvbuff_t *tvb, proto_tree *tree, guint offset)
2549 offset = fObjectIdentifier (tvb, tree, offset);
2550 return fAddress (tvb, tree, offset);
2554 fActionCommand (tvbuff_t *tvb, proto_tree *tree, guint offset)
2556 guint lastoffset = 0;
2557 guint8 tag_no, tag_info;
2559 proto_tree *subtree = tree;
2562 /* set the optional global properties to indicate not-used */
2563 propertyArrayIndex = -1;
2564 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
2565 lastoffset = offset;
2566 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
2567 if (tag_is_closing(tag_info)) {
2568 offset += fTagHeaderTree (tvb, subtree, offset,
2569 &tag_no, &tag_info, &lvt);
2575 case 0: /* deviceIdentifier */
2576 offset = fObjectIdentifier (tvb, subtree, offset);
2578 case 1: /* objectIdentifier */
2579 offset = fObjectIdentifier (tvb, subtree, offset);
2581 case 2: /* propertyIdentifier */
2582 offset = fPropertyIdentifier (tvb, subtree, offset);
2584 case 3: /* propertyArrayIndex */
2585 offset = fPropertyArrayIndex (tvb, subtree, offset);
2587 case 4: /* propertyValue */
2588 if (tag_is_opening(tag_info)) {
2589 tt = proto_tree_add_text(subtree, tvb, offset, 1, "propertyValue");
2590 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
2591 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
2592 offset = fAbstractSyntaxNType (tvb, subtree, offset);
2597 case 5: /* priority */
2598 offset = fUnsignedTag (tvb,subtree,offset,"Priority: ");
2600 case 6: /* postDelay */
2601 offset = fUnsignedTag (tvb,subtree,offset,"Post Delay: ");
2603 case 7: /* quitOnFailure */
2604 offset = fBooleanTag(tvb, subtree, offset,
2605 "Quit On Failure: ");
2607 case 8: /* writeSuccessful */
2608 offset = fBooleanTag(tvb, subtree, offset,
2609 "Write Successful: ");
2619 fActionList (tvbuff_t *tvb, proto_tree *tree, guint offset)
2621 return fActionCommand (tvb,tree,offset);
2625 fPropertyIdentifier (tvbuff_t *tvb, proto_tree *tree, guint offset)
2627 guint8 tag_no, tag_info;
2631 proto_tree *subtree;
2632 const gchar *label = "Property Identifier";
2634 propertyIdentifier = 0; /* global Variable */
2635 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
2636 /* can we decode this value? */
2637 if (fUnsigned32 (tvb, offset+tag_len, lvt, (guint32 *)&propertyIdentifier)) {
2638 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
2639 "%s: %s (%u)", label,
2640 val_to_split_str(propertyIdentifier, 512,
2641 BACnetPropertyIdentifier,
2642 ASHRAE_Reserved_Fmt,
2643 Vendor_Proprietary_Fmt), propertyIdentifier);
2645 /* property identifiers cannot be larger than 22-bits */
2648 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
2649 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
2650 proto_tree_add_item(subtree, hf_BACnetPropertyIdentifier, tvb,
2651 offset+tag_len, lvt, FALSE);
2653 return offset+tag_len+lvt;
2657 fPropertyArrayIndex (tvbuff_t *tvb, proto_tree *tree, guint offset)
2659 guint8 tag_no, tag_info;
2663 proto_tree *subtree;
2665 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
2666 if (fUnsigned32 (tvb, offset + tag_len, lvt, (guint32 *)&propertyArrayIndex))
2667 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
2668 "property Array Index (Unsigned) %u", propertyArrayIndex);
2670 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
2671 "property Array Index - %u octets (Unsigned)", lvt);
2672 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
2673 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
2675 return offset+tag_len+lvt;
2679 fCharacterString (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
2681 guint8 tag_no, tag_info, character_set;
2683 size_t inbytesleft, outbytesleft = 512;
2684 guint offs, extra = 1;
2686 guint8 bf_arr[512], *out = &bf_arr[0];
2688 proto_tree *subtree;
2689 guint start = offset;
2691 if (tvb_length_remaining(tvb, offset) > 0) {
2693 offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
2695 character_set = tvb_get_guint8(tvb, offset+offs);
2696 /* Account for code page if DBCS */
2697 if (character_set == 1)
2701 offset += (offs+extra);
2705 inbytesleft = l = min(lvt, 255);
2707 * XXX - are we guaranteed that these encoding
2708 * names correspond, on *all* platforms with
2709 * iconv(), to the encodings we want?
2710 * If not (and perhaps even if so), we should
2711 * perhaps have our own iconv() implementation,
2712 * with a different name, so that we control the
2713 * encodings it supports and the names of those
2716 * We should also handle that in the general
2717 * string handling code, rather than making it
2718 * specific to the BACAPP dissector, as many
2719 * other dissectors need to handle various
2720 * character encodings.
2722 str_val = tvb_get_ephemeral_string(tvb, offset, l);
2723 /** this decoding may be not correct for multi-byte characters, Lka */
2724 switch (character_set) {
2726 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "ANSI_X3.4");
2734 case ISO_10646_UCS4:
2735 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UCS-4BE");
2737 case ISO_10646_UCS2:
2738 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "UCS-2BE");
2741 fConvertXXXtoUTF8(str_val, &inbytesleft, out, &outbytesleft, "ISO8859-1");
2747 ti = proto_tree_add_text(tree, tvb, offset, l, "%s'%s'", label, out);
2752 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
2754 fTagHeaderTree (tvb, subtree, start, &tag_no, &tag_info, &lvt);
2755 proto_tree_add_item(subtree, hf_BACnetCharacterSet, tvb, start+offs, 1, FALSE);
2757 if (character_set == 1)
2759 proto_tree_add_text(subtree, tvb, start+offs+1, 2, "Code Page: %d", tvb_get_ntohs(tvb, start+offs+1));
2766 fBitStringTagVS (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label,
2767 const value_string *src)
2769 guint8 tag_no, tag_info, tmp;
2770 gint j, unused, skip;
2771 guint start = offset;
2773 guint32 lvt, i, numberOfBytes;
2775 proto_tree* subtree = tree;
2778 offs = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
2779 numberOfBytes = lvt-1; /* Ignore byte for unused bit count */
2781 unused = tvb_get_guint8(tvb, offset); /* get the unused Bits */
2782 ti = proto_tree_add_text(tree, tvb, start, offs+lvt,
2786 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
2788 fTagHeaderTree(tvb, subtree, start, &tag_no, &tag_info, &lvt);
2789 proto_tree_add_text(subtree, tvb, offset, 1,
2793 for (i = 0; i < numberOfBytes; i++) {
2794 tmp = tvb_get_guint8(tvb, (offset)+i+1);
2795 if (i == numberOfBytes-1) { skip = unused; }
2796 for (j = 0; j < 8-skip; j++) {
2798 if (tmp & (1 << (7 - j)))
2799 proto_tree_add_text(subtree, tvb,
2802 val_to_str((guint) (i*8 +j),
2804 ASHRAE_Reserved_Fmt));
2806 proto_tree_add_text(subtree, tvb,
2809 val_to_str((guint) (i*8 +j),
2811 ASHRAE_Reserved_Fmt));
2813 bf_arr[min(255,(i*8)+j)] = tmp & (1 << (7 - j)) ? '1' : '0';
2820 bf_arr[min(255,numberOfBytes*8-unused)] = 0;
2821 proto_tree_add_text(subtree, tvb, offset, lvt, "B'%s'", bf_arr);
2830 fBitStringTag (tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
2832 return fBitStringTagVS (tvb, tree, offset, label, NULL);
2835 /* handles generic application types, as well as enumerated and enumerations
2836 with reserved and proprietarty ranges (split) */
2838 fApplicationTypesEnumeratedSplit (tvbuff_t *tvb, proto_tree *tree, guint offset,
2839 const gchar *label, const value_string *src, guint32 split_val)
2841 guint8 tag_no, tag_info;
2845 if (tvb_length_remaining(tvb, offset) > 0) {
2847 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
2848 if (!tag_is_context_specific(tag_info))
2851 case 0: /** NULL 20.2.2 */
2852 offset = fNullTag(tvb, tree, offset, label);
2854 case 1: /** BOOLEAN 20.2.3 */
2855 offset = fBooleanTag(tvb, tree, offset, label);
2857 case 2: /** Unsigned Integer 20.2.4 */
2858 offset = fUnsignedTag(tvb, tree, offset, label);
2860 case 3: /** Signed Integer 20.2.5 */
2861 offset = fSignedTag(tvb, tree, offset, label);
2863 case 4: /** Real 20.2.6 */
2864 offset = fRealTag(tvb, tree, offset, label);
2866 case 5: /** Double 20.2.7 */
2867 offset = fDoubleTag(tvb, tree, offset, label);
2869 case 6: /** Octet String 20.2.8 */
2870 offset = fOctetString (tvb, tree, offset, label, lvt);
2872 case 7: /** Character String 20.2.9 */
2873 offset = fCharacterString (tvb,tree,offset,label);
2875 case 8: /** Bit String 20.2.10 */
2876 offset = fBitStringTagVS (tvb, tree, offset, label, src);
2878 case 9: /** Enumerated 20.2.11 */
2879 offset = fEnumeratedTagSplit (tvb, tree, offset, label, src, split_val);
2881 case 10: /** Date 20.2.12 */
2882 offset = fDate (tvb, tree, offset, label);
2884 case 11: /** Time 20.2.13 */
2885 offset = fTime (tvb, tree, offset, label);
2887 case 12: /** BACnetObjectIdentifier 20.2.14 */
2888 offset = fObjectIdentifier (tvb, tree, offset);
2890 case 13: /* reserved for ASHRAE */
2893 proto_tree_add_text(tree, tvb, offset, lvt+tag_len, "%s'reserved for ASHRAE'", label);
2894 offset+=lvt+tag_len;
2906 fShedLevel (tvbuff_t *tvb, proto_tree *tree, guint offset)
2908 guint lastoffset = 0;
2910 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
2911 lastoffset = offset;
2913 switch (fTagNo(tvb,offset)) {
2914 case 0: /* percent */
2915 offset = fUnsignedTag (tvb, tree, offset, "shed percent: ");
2918 offset = fUnsignedTag (tvb, tree, offset, "shed level: ");
2920 case 2: /* amount */
2921 offset = fRealTag(tvb, tree, offset, "shed amount: ");
2931 fApplicationTypesEnumerated (tvbuff_t *tvb, proto_tree *tree, guint offset,
2932 const gchar *label, const value_string *vs)
2934 return fApplicationTypesEnumeratedSplit(tvb, tree, offset, label, vs, 0);
2938 fApplicationTypes (tvbuff_t *tvb, proto_tree *tree, guint offset,
2941 return fApplicationTypesEnumeratedSplit(tvb, tree, offset, label, NULL, 0);
2945 fContextTaggedValue(tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
2947 guint8 tag_no, tag_info;
2951 proto_tree *subtree;
2955 tag_len = fTagHeader(tvb, offset, &tag_no, &tag_info, &lvt);
2956 /* cap the the suggested length in case of bad data */
2957 tvb_len = tvb_length_remaining(tvb, offset+tag_len);
2958 if ((tvb_len >= 0) && ((guint32)tvb_len < lvt))
2962 ti = proto_tree_add_text(tree, tvb, offset+tag_len, lvt,
2963 "Context Value (as %u DATA octets)", lvt);
2965 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
2966 fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
2968 return offset + tag_len + lvt;
2972 fAbstractSyntaxNType (tvbuff_t *tvb, proto_tree *tree, guint offset)
2974 guint8 tag_no, tag_info;
2976 guint lastoffset = 0, depth = 0;
2979 if (propertyIdentifier >= 0)
2981 g_snprintf (ar, sizeof(ar), "%s: ",
2982 val_to_split_str(propertyIdentifier, 512,
2983 BACnetPropertyIdentifier,
2984 ASHRAE_Reserved_Fmt,
2985 Vendor_Proprietary_Fmt));
2989 g_snprintf (ar, sizeof(ar), "Abstract Type: ");
2991 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
2992 lastoffset = offset;
2993 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
2994 if (tag_is_closing(tag_info)) { /* closing tag, but not for me */
2995 if (depth <= 0) return offset;
2998 /* Application Tags */
2999 switch (propertyIdentifier) {
3000 case 2: /* BACnetActionList */
3001 offset = fActionList (tvb,tree,offset);
3003 case 30: /* BACnetAddressBinding */
3004 offset = fAddressBinding (tvb,tree,offset);
3006 case 55: /* list-of-session-keys */
3007 fSessionKey (tvb, tree, offset);
3009 case 79: /* object-type */
3010 case 96: /* protocol-object-types-supported */
3011 offset = fApplicationTypesEnumeratedSplit (tvb, tree, offset, ar,
3012 BACnetObjectType, 128);
3014 case 97: /* Protocol-Services-Supported */
3015 offset = fApplicationTypesEnumerated (tvb, tree, offset, ar,
3016 BACnetServicesSupported);
3018 case 107: /* segmentation-supported */
3019 offset = fApplicationTypesEnumerated (tvb, tree, offset, ar,
3020 BACnetSegmentation);
3022 case 111: /* Status-Flags */
3023 offset = fApplicationTypesEnumerated (tvb, tree, offset, ar,
3026 case 112: /* System-Status */
3027 offset = fApplicationTypesEnumerated (tvb, tree, offset, ar,
3028 BACnetDeviceStatus);
3030 case 117: /* units */
3031 offset = fApplicationTypesEnumerated (tvb, tree, offset, ar,
3032 BACnetEngineeringUnits);
3034 case 87: /* priority-array -- accessed as a BACnetARRAY */
3035 if (propertyArrayIndex == 0) {
3036 /* BACnetARRAY index 0 refers to the length
3037 of the array, not the elements of the array */
3038 offset = fApplicationTypes (tvb, tree, offset, ar);
3040 offset = fPriorityArray (tvb, tree, offset);
3043 case 38: /* exception-schedule */
3044 if (object_type < 128)
3046 offset = fSpecialEvent (tvb,tree,offset);
3049 case 123: /* weekly-schedule -- accessed as a BACnetARRAY */
3050 if (object_type < 128)
3052 if (propertyArrayIndex == 0) {
3053 /* BACnetARRAY index 0 refers to the length
3054 of the array, not the elements of the array */
3055 offset = fApplicationTypes (tvb, tree, offset, ar);
3057 offset = fWeeklySchedule (tvb,tree,offset);
3061 case 159: /* member-of */
3062 case 165: /* zone-members */
3063 offset = fDeviceObjectReference (tvb, tree, offset);
3065 case 212: /* actual-shed-level */
3066 case 214: /* expected-shed-level */
3067 case 218: /* requested-shed-level */
3068 offset = fShedLevel (tvb, tree, offset);
3073 if (tag_is_opening(tag_info))
3076 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
3078 else if (tag_is_closing(tag_info))
3081 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
3085 offset = fContextTaggedValue(tvb, tree, offset, ar);
3090 offset = fApplicationTypes (tvb, tree, offset, ar);
3100 fPropertyValue (tvbuff_t *tvb, proto_tree *tree, guint offset, guint8 tagoffset)
3102 guint lastoffset = offset;
3104 proto_tree *subtree;
3105 guint8 tag_no, tag_info;
3108 offset = fPropertyReference(tvb, tree, offset, tagoffset, 0);
3109 if (offset > lastoffset)
3111 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
3112 if (tag_no == tagoffset+2) { /* Value - might not be present in ReadAccessResult */
3113 if (tag_is_opening(tag_info)) {
3114 tt = proto_tree_add_text(tree, tvb, offset, 1, "propertyValue");
3115 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
3116 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
3117 offset = fAbstractSyntaxNType (tvb, subtree, offset);
3118 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
3126 fBACnetPropertyValue (tvbuff_t *tvb, proto_tree *tree, guint offset)
3128 guint lastoffset = 0;
3129 guint8 tag_no, tag_info;
3132 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
3133 lastoffset = offset;
3134 offset = fPropertyValue(tvb, tree, offset, 0);
3135 if (offset > lastoffset)
3137 /* detect optional priority
3138 by looking to see if the next tag is context tag number 3 */
3139 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
3140 if (tag_is_context_specific(tag_info) && (tag_no == 3))
3141 offset = fUnsignedTag (tvb,tree,offset,"Priority: ");
3148 fSubscribeCOVPropertyRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
3150 guint lastoffset = 0;
3151 guint8 tag_no, tag_info;
3153 proto_tree *subtree = tree;
3156 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
3157 lastoffset = offset;
3158 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
3159 if (tag_is_closing(tag_info)) {
3160 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
3166 case 0: /* ProcessId */
3167 offset = fUnsignedTag (tvb, tree, offset, "subscriber Process Id: ");
3169 case 1: /* monitored ObjectId */
3170 offset = fObjectIdentifier (tvb, tree, offset);
3172 case 2: /* issueConfirmedNotifications */
3173 offset = fBooleanTag (tvb, tree, offset, "issue Confirmed Notifications: ");
3175 case 3: /* life time */
3176 offset = fTimeSpan (tvb,tree,offset,"life time");
3178 case 4: /* monitoredPropertyIdentifier */
3179 if (tag_is_opening(tag_info)) {
3180 tt = proto_tree_add_text(subtree, tvb, offset, 1, "monitoredPropertyIdentifier");
3182 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
3184 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
3185 offset = fBACnetPropertyReference (tvb, subtree, offset, 1);
3190 case 5: /* covIncrement */
3191 offset = fRealTag (tvb, tree, offset, "COV Increment: ");
3201 fSubscribeCOVRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
3203 return fSubscribeCOVPropertyRequest(tvb, tree, offset);
3207 fWhoHas (tvbuff_t *tvb, proto_tree *tree, guint offset)
3209 guint lastoffset = 0;
3211 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
3212 lastoffset = offset;
3214 switch (fTagNo(tvb, offset)) {
3215 case 0: /* deviceInstanceLowLimit */
3216 offset = fUnsignedTag (tvb, tree, offset, "device Instance Low Limit: ");
3218 case 1: /* deviceInstanceHighLimit */
3219 offset = fUnsignedTag (tvb, tree, offset, "device Instance High Limit: ");
3221 case 2: /* BACnetObjectId */
3222 offset = fObjectIdentifier (tvb, tree, offset);
3224 case 3: /* messageText */
3225 offset = fCharacterString (tvb,tree,offset, "Object Name: ");
3236 fDailySchedule (tvbuff_t *tvb, proto_tree *subtree, guint offset)
3238 guint lastoffset = 0;
3239 guint8 tag_no, tag_info;
3242 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
3243 if (tag_is_opening(tag_info) && tag_no == 0)
3245 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt); /* opening context tag 0 */
3246 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
3247 lastoffset = offset;
3248 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
3249 if (tag_is_closing(tag_info)) {
3250 /* should be closing context tag 0 */
3251 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
3255 offset = fTimeValue (tvb, subtree, offset);
3258 else if (tag_no == 0 && lvt == 0)
3260 /* not sure null (empty array element) is legal */
3261 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
3267 fWeeklySchedule (tvbuff_t *tvb, proto_tree *tree, guint offset)
3269 guint lastoffset = 0;
3270 guint8 tag_no, tag_info;
3272 guint i = 1; /* day of week array index */
3273 proto_tree *subtree = tree;
3276 if (propertyArrayIndex > 0) {
3277 /* BACnetARRAY index 0 refers to the length
3278 of the array, not the elements of the array.
3279 BACnetARRAY index -1 is our internal flag that
3280 the optional index was not used.
3281 BACnetARRAY refers to this as all elements of the array.
3282 If the optional index is specified for a BACnetARRAY,
3283 then that specific array element is referenced. */
3284 i = propertyArrayIndex;
3286 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
3287 lastoffset = offset;
3288 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
3289 if (tag_is_closing(tag_info)) {
3290 return offset; /* outer encoding will print out closing tag */
3292 tt = proto_tree_add_text(tree, tvb, offset, 0, "%s", val_to_str(i++, day_of_week, "day of week (%d) not found"));
3293 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
3294 offset = fDailySchedule (tvb,subtree,offset);
3301 fUTCTimeSynchronizationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
3303 if (tvb_length_remaining(tvb, offset) <= 0)
3306 return fDateTime (tvb, tree, offset, "UTC-Time: ");
3310 fTimeSynchronizationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
3312 if (tvb_length_remaining(tvb, offset) <= 0)
3315 return fDateTime (tvb, tree, offset, NULL);
3319 fDateRange (tvbuff_t *tvb, proto_tree *tree, guint offset)
3321 if (tvb_length_remaining(tvb, offset) <= 0)
3323 offset = fDate (tvb,tree,offset,"Start Date: ");
3324 return fDate (tvb, tree, offset, "End Date: ");
3328 fVendorIdentifier (tvbuff_t *tvb, proto_tree *tree, guint offset)
3331 guint8 tag_no, tag_info;
3335 proto_tree *subtree;
3336 const gchar *label = "Vendor ID";
3338 tag_len = fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
3339 if (fUnsigned32 (tvb, offset + tag_len, lvt, &val))
3340 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
3341 "%s: %s (%u)", label,
3342 val_to_str(val,BACnetVendorIdentifiers,"Unknown Vendor"), val);
3344 ti = proto_tree_add_text(tree, tvb, offset, lvt+tag_len,
3345 "%s - %u octets (Unsigned)", label, lvt);
3346 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
3347 fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
3348 proto_tree_add_item(subtree, hf_BACnetVendorIdentifier, tvb,
3349 offset+tag_len, lvt, FALSE);
3351 return offset+tag_len+lvt;
3355 fConfirmedTextMessageRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
3357 guint lastoffset = 0;
3359 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
3360 lastoffset = offset;
3361 switch (fTagNo(tvb, offset)) {
3363 case 0: /* textMessageSourceDevice */
3364 offset = fObjectIdentifier (tvb, tree, offset);
3366 case 1: /* messageClass */
3367 switch (fTagNo(tvb, offset)) {
3368 case 0: /* numeric */
3369 offset = fUnsignedTag (tvb, tree, offset, "message Class: ");
3371 case 1: /* character */
3372 offset = fCharacterString (tvb, tree, offset, "message Class: ");
3376 case 2: /* messagePriority */
3377 offset = fEnumeratedTag (tvb, tree, offset, "message Priority: ",
3378 BACnetMessagePriority);
3380 case 3: /* message */
3381 offset = fCharacterString (tvb, tree, offset, "message: ");
3391 fUnconfirmedTextMessageRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
3393 return fConfirmedTextMessageRequest(tvb, tree, offset);
3397 fConfirmedPrivateTransferRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
3399 guint lastoffset = 0;
3400 guint8 tag_no, tag_info;
3402 proto_tree *subtree = tree;
3405 /* exit loop if nothing happens inside */
3406 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
3407 lastoffset = offset;
3408 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
3409 if (tag_is_closing(tag_info)) {
3410 if (tag_no == 2) /* Make sure it's the expected tag */
3412 offset += fTagHeaderTree (tvb, subtree, offset,
3413 &tag_no, &tag_info, &lvt);
3419 break; /* End loop if incorrect closing tag */
3424 case 0: /* vendorID */
3425 offset = fVendorIdentifier (tvb, subtree, offset);
3427 case 1: /* serviceNumber */
3428 offset = fUnsignedTag (tvb, subtree, offset, "service Number: ");
3430 case 2: /*serviceParameters */
3431 if (tag_is_opening(tag_info)) {
3432 tt = proto_tree_add_text(subtree, tvb, offset, 1, "service Parameters");
3433 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
3434 propertyIdentifier = -1;
3435 offset = fAbstractSyntaxNType (tvb, subtree, offset);
3448 fUnconfirmedPrivateTransferRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
3450 return fConfirmedPrivateTransferRequest(tvb, tree, offset);
3454 fConfirmedPrivateTransferAck(tvbuff_t *tvb, proto_tree *tree, guint offset)
3456 return fConfirmedPrivateTransferRequest(tvb, tree, offset);
3460 fLifeSafetyOperationRequest(tvbuff_t *tvb, proto_tree *tree, guint offset, const gchar *label)
3462 guint lastoffset = 0;
3463 guint8 tag_no, tag_info;
3465 proto_tree *subtree = tree;
3468 if (label != NULL) {
3469 tt = proto_tree_add_text (subtree, tvb, offset, 1, "%s", label);
3470 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
3473 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
3474 lastoffset = offset;
3475 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
3478 case 0: /* subscriberProcessId */
3479 offset = fUnsignedTag (tvb, subtree, offset, "requesting Process Id: ");
3481 case 1: /* requestingSource */
3482 offset = fCharacterString (tvb, tree, offset, "requesting Source: ");
3484 case 2: /* request */
3485 offset = fEnumeratedTagSplit (tvb, tree, offset,
3486 "request: ", BACnetLifeSafetyOperation, 64);
3488 case 3: /* objectId */
3489 offset = fObjectIdentifier (tvb, subtree, offset);
3498 static guint fBACnetPropertyStates(tvbuff_t *tvb, proto_tree *tree, guint offset)
3500 switch (fTagNo(tvb, offset))
3503 offset = fBooleanTag (tvb, tree, offset, "boolean-value: ");
3506 offset = fEnumeratedTagSplit (tvb, tree, offset,
3507 "binary-value: ", BACnetBinaryPV, 2);
3510 offset = fEnumeratedTagSplit (tvb, tree, offset,
3511 "event-type: ", BACnetEventType, 12);
3514 offset = fEnumeratedTagSplit (tvb, tree, offset,
3515 "polarity: ", BACnetPolarity, 2);
3518 offset = fEnumeratedTagSplit (tvb, tree, offset,
3519 "program-change: ", BACnetProgramRequest, 5);
3522 offset = fEnumeratedTagSplit (tvb, tree, offset,
3523 "program-state: ", BACnetProgramState, 5);
3526 offset = fEnumeratedTagSplit (tvb, tree, offset,
3527 "reason-for-halt: ", BACnetProgramError, 5);
3530 offset = fEnumeratedTagSplit (tvb, tree, offset,
3531 "reliability: ", BACnetReliability, 10);
3534 offset = fEnumeratedTagSplit (tvb, tree, offset,
3535 "state: ", BACnetEventState, 64);
3538 offset = fEnumeratedTagSplit (tvb, tree, offset,
3539 "system-status: ", BACnetDeviceStatus, 64);
3542 offset = fEnumeratedTagSplit (tvb, tree, offset,
3543 "units: ", BACnetEngineeringUnits, 2);
3546 offset = fUnsignedTag(tvb, tree, offset, "unsigned-value: ");
3549 offset = fEnumeratedTagSplit (tvb, tree, offset,
3550 "life-safety-mode: ", BACnetLifeSafetyMode, 64);
3553 offset = fEnumeratedTagSplit (tvb, tree, offset,
3554 "life-safety-state: ", BACnetLifeSafetyState, 64);
3564 BACnetDeviceObjectPropertyValue ::= SEQUENCE {
3565 deviceIdentifier [0] BACnetObjectIdentifier,
3566 objectIdentifier [1] BACnetObjectIdentifier,
3567 propertyIdentifier [2] BACnetPropertyIdentifier,
3568 arrayIndex [3] Unsigned OPTIONAL,
3569 value [4] ABSTRACT-SYNTAX.&Type
3573 fDeviceObjectPropertyValue (tvbuff_t *tvb, proto_tree *tree, guint offset)
3575 guint lastoffset = 0;
3576 guint8 tag_no, tag_info;
3579 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
3580 lastoffset = offset;
3581 /* check the tag. A closing tag means we are done */
3582 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
3583 if (tag_is_closing(tag_info)) {
3587 case 0: /* deviceIdentifier */
3588 offset = fObjectIdentifier (tvb, tree, offset);
3590 case 1: /* objectIdentifier */
3591 offset = fObjectIdentifier (tvb, tree, offset);
3593 case 2: /* propertyIdentifier */
3594 offset = fPropertyIdentifier (tvb, tree, offset);
3596 case 3: /* arrayIndex - OPTIONAL */
3597 offset = fUnsignedTag (tvb, tree, offset,
3601 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
3602 offset = fAbstractSyntaxNType (tvb, tree, offset);
3603 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
3614 BACnetDeviceObjectPropertyReference ::= SEQUENCE {
3615 objectIdentifier [0] BACnetObjectIdentifier,
3616 propertyIdentifier [1] BACnetPropertyIdentifier,
3617 propertyArrayIndex [2] Unsigned OPTIONAL, -- used only with array datatype
3618 -- if omitted with an array then
3619 -- the entire array is referenced
3620 deviceIdentifier [3] BACnetObjectIdentifier OPTIONAL
3624 fDeviceObjectPropertyReference (tvbuff_t *tvb, proto_tree *tree, guint offset)
3626 guint lastoffset = 0;
3627 guint8 tag_no, tag_info;
3630 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
3631 lastoffset = offset;
3632 /* check the tag. A closing tag means we are done */
3633 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
3634 if (tag_is_closing(tag_info)) {
3638 case 0: /* objectIdentifier */
3639 offset = fObjectIdentifier (tvb, tree, offset);
3641 case 1: /* propertyIdentifier */
3642 offset = fPropertyIdentifier (tvb, tree, offset);
3644 case 2: /* arrayIndex - OPTIONAL */
3645 offset = fUnsignedTag (tvb, tree, offset,
3648 case 3: /* deviceIdentifier - OPTIONAL */
3649 offset = fObjectIdentifier (tvb, tree, offset);
3659 fNotificationParameters (tvbuff_t *tvb, proto_tree *tree, guint offset)
3661 guint lastoffset = offset;
3662 guint8 tag_no, tag_info;
3664 proto_tree *subtree = tree;
3667 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
3668 tt = proto_tree_add_text(subtree, tvb, offset, 0, "notification parameters (%d) %s",
3669 tag_no, val_to_str(tag_no, BACnetEventType, "invalid type"));
3670 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
3671 /* Opening tag for parameter choice */
3672 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
3675 case 0: /* change-of-bitstring */
3676 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
3677 lastoffset = offset;
3678 switch (fTagNo(tvb, offset)) {
3680 offset = fBitStringTag (tvb, subtree, offset,
3681 "referenced-bitstring: ");
3684 offset = fBitStringTagVS (tvb, subtree, offset,
3685 "status-flags: ", BACnetStatusFlags);
3692 case 1: /* change-of-state */
3693 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
3694 lastoffset = offset;
3695 switch (fTagNo(tvb, offset)) {
3697 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
3698 offset = fBACnetPropertyStates(tvb, subtree, offset);
3699 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
3702 offset = fBitStringTagVS (tvb, subtree, offset,
3703 "status-flags: ", BACnetStatusFlags);
3704 lastoffset = offset;
3711 case 2: /* change-of-value */
3712 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
3713 lastoffset = offset;
3714 switch (fTagNo(tvb, offset)) {
3716 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
3717 switch (fTagNo(tvb, offset)) {
3719 offset = fBitStringTag (tvb, subtree, offset,
3723 offset = fRealTag (tvb, subtree, offset,
3729 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
3732 offset = fBitStringTagVS (tvb, subtree, offset,
3733 "status-flags: ", BACnetStatusFlags);
3740 case 3: /* command-failure */
3741 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
3742 lastoffset = offset;
3743 switch (fTagNo(tvb, offset)) {
3744 case 0: /* "command-value: " */
3745 /* from BACnet Table 13-3,
3746 Standard Object Property Values Returned in Notifications */
3747 propertyIdentifier = 85; /* PRESENT_VALUE */
3748 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
3749 offset = fAbstractSyntaxNType (tvb, subtree, offset);
3750 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
3753 offset = fBitStringTagVS (tvb, subtree, offset,
3754 "status-flags: ", BACnetStatusFlags);
3756 case 2: /* "feedback-value: " */
3757 propertyIdentifier = 40; /* FEEDBACK_VALUE */
3758 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
3759 offset = fAbstractSyntaxNType (tvb, subtree, offset);
3760 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
3767 case 4: /* floating-limit */
3768 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
3769 lastoffset = offset;
3770 switch (fTagNo(tvb, offset)) {
3772 offset = fRealTag (tvb, subtree, offset, "reference-value: ");
3775 offset = fBitStringTagVS (tvb, subtree, offset,
3776 "status-flags: ", BACnetStatusFlags);
3779 offset = fRealTag (tvb, subtree, offset, "setpoint-value: ");
3782 offset = fRealTag (tvb, subtree, offset, "error-limit: ");
3789 case 5: /* out-of-range */
3790 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
3791 lastoffset = offset;
3792 switch (fTagNo(tvb, offset)) {
3794 offset = fRealTag (tvb, subtree, offset, "exceeding-value: ");
3797 offset = fBitStringTagVS (tvb, subtree, offset,
3798 "status-flags: ", BACnetStatusFlags);
3801 offset = fRealTag (tvb, subtree, offset, "deadband: ");
3804 offset = fRealTag (tvb, subtree, offset, "exceeded-limit: ");
3812 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
3813 lastoffset = offset;
3814 offset =fBACnetPropertyValue (tvb,subtree,offset);
3817 case 7: /* buffer-ready */
3818 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
3819 lastoffset = offset;
3820 switch (fTagNo(tvb, offset)) {
3822 offset = fObjectIdentifier (tvb, subtree, offset); /* buffer-device */
3825 offset = fObjectIdentifier (tvb, subtree, offset); /* buffer-object */
3828 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
3829 offset = fDateTime (tvb, subtree, offset, "previous-notification: ");
3830 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
3833 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
3834 offset = fDateTime (tvb, subtree, offset, "current-notification: ");
3835 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
3842 case 8: /* change-of-life-safety */
3843 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
3844 lastoffset = offset;
3845 switch (fTagNo(tvb, offset)) {
3847 offset = fEnumeratedTagSplit (tvb, subtree, offset,
3848 "new-state: ", BACnetLifeSafetyState, 256);
3851 offset = fEnumeratedTagSplit (tvb, subtree, offset,
3852 "new-mode: ", BACnetLifeSafetyMode, 256);
3855 offset = fBitStringTagVS (tvb, subtree, offset,
3856 "status-flags: ", BACnetStatusFlags);
3859 offset = fEnumeratedTagSplit (tvb, subtree, offset,
3860 "operation-expected: ", BACnetLifeSafetyOperation, 64);
3867 case 9: /* extended */
3868 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
3869 lastoffset = offset;
3870 switch (fTagNo(tvb, offset)) {
3872 offset = fVendorIdentifier (tvb, subtree, offset);
3875 offset = fUnsignedTag (tvb, subtree, offset,
3876 "extended-event-type: ");
3878 case 2: /* parameters */
3879 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
3880 offset = fApplicationTypes(tvb, subtree, offset, "parameters: ");
3881 offset = fDeviceObjectPropertyValue(tvb, subtree, offset);
3882 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
3889 case 10: /* buffer ready */
3890 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
3891 lastoffset = offset;
3892 switch (fTagNo(tvb, offset)) {
3893 case 0: /* buffer-property */
3894 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
3895 offset = fDeviceObjectPropertyReference (tvb, subtree, offset);
3896 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
3899 offset = fUnsignedTag (tvb, subtree, offset,
3900 "previous-notification: ");
3903 offset = fUnsignedTag (tvb, subtree, offset,
3904 "current-notification: ");
3911 case 11: /* unsigned range */
3912 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
3913 lastoffset = offset;
3914 switch (fTagNo(tvb, offset)) {
3916 offset = fUnsignedTag (tvb, subtree, offset,
3917 "exceeding-value: ");
3920 offset = fBitStringTagVS (tvb, subtree, offset,
3921 "status-flags: ", BACnetStatusFlags);
3924 offset = fUnsignedTag (tvb, subtree, offset,
3925 "exceeded-limit: ");
3936 /* Closing tag for parameter choice */
3937 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
3944 fEventParameter (tvbuff_t *tvb, proto_tree *tree, guint offset)
3946 guint lastoffset = 0;
3948 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
3949 lastoffset = offset;
3950 switch (fTagNo(tvb, offset)) {
3951 case 0: /* change-of-bitstring */
3952 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
3953 lastoffset = offset;
3954 switch (fTagNo(tvb, offset)) {
3956 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
3959 offset = fBitStringTag (tvb, tree, offset, "bitmask: ");
3961 case 2: /* SEQUENCE OF BIT STRING */
3962 offset = fBitStringTagVS (tvb, tree, offset,
3963 "bitstring value: ", BACnetEventTransitionBits);
3970 case 1: /* change-of-state */
3971 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
3972 lastoffset = offset;
3973 switch (fTagNo(tvb, offset)) {
3975 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
3977 case 1: /* SEQUENCE OF BACnetPropertyStates */
3978 offset = fEnumeratedTagSplit (tvb, tree, offset,
3979 "value: ", BACnetPropertyStates, 64);
3986 case 2: /* change-of-value */
3987 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
3988 lastoffset = offset;
3989 switch (fTagNo(tvb, offset)) {
3991 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
3993 case 1: /* don't loop it, it's a CHOICE */
3994 switch (fTagNo(tvb, offset)) {
3996 offset = fBitStringTag (tvb, tree, offset, "bitmask: ");
3999 offset = fRealTag (tvb, tree, offset,
4000 "referenced Property Increment: ");
4010 case 3: /* command-failure */
4011 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4012 lastoffset = offset;
4013 switch (fTagNo(tvb, offset)) {
4015 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
4018 offset = fDeviceObjectPropertyReference (tvb,tree,offset);
4024 case 4: /* floating-limit */
4025 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4026 lastoffset = offset;
4027 switch (fTagNo(tvb, offset)) {
4029 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
4032 offset = fDeviceObjectPropertyReference (tvb,tree,offset);
4035 offset = fRealTag (tvb, tree, offset, "low diff limit: ");
4038 offset = fRealTag (tvb, tree, offset, "high diff limit: ");
4041 offset = fRealTag (tvb, tree, offset, "deadband: ");
4048 case 5: /* out-of-range */
4049 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4050 lastoffset = offset;
4051 switch (fTagNo(tvb, offset)) {
4053 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
4056 offset = fRealTag (tvb, tree, offset, "low limit: ");
4059 offset = fRealTag (tvb, tree, offset, "high limit: ");
4062 offset = fRealTag (tvb, tree, offset, "deadband: ");
4070 offset = fBACnetPropertyValue (tvb,tree,offset);
4072 case 7: /* buffer-ready */
4073 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4074 lastoffset = offset;
4075 switch (fTagNo(tvb, offset)) {
4077 offset = fUnsignedTag (tvb,tree,offset,"notification threshold");
4080 offset = fUnsignedTag (tvb,tree,offset,
4081 "previous notification count: ");
4088 case 8: /* change-of-life-safety */
4089 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4090 lastoffset = offset;
4091 switch (fTagNo(tvb, offset)) {
4093 offset = fTimeSpan (tvb, tree, offset, "Time Delay");
4096 offset = fEnumeratedTagSplit (tvb, tree, offset,
4097 "life safety alarm value: ", BACnetLifeSafetyState, 256);
4100 offset = fEnumeratedTagSplit (tvb, tree, offset,
4101 "alarm value: ", BACnetLifeSafetyState, 256);
4104 offset = fDeviceObjectPropertyReference (tvb, tree, offset);
4119 fLogRecord (tvbuff_t *tvb, proto_tree *tree, guint offset)
4121 guint lastoffset = 0;
4122 guint8 tag_no, tag_info;
4125 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4126 lastoffset = offset;
4127 switch (fTagNo(tvb, offset)) {
4128 case 0: /* timestamp */
4129 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4130 offset = fDateTime (tvb,tree,offset,NULL);
4131 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4133 case 1: /* logDatum: don't loop, it's a CHOICE */
4134 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4135 switch (fTagNo(tvb, offset)) {
4136 case 0: /* logStatus */
4137 offset = fEnumeratedTag (tvb, tree, offset,
4138 "log status: ", BACnetLogStatus);
4141 offset = fBooleanTag (tvb, tree, offset, "boolean-value: ");
4144 offset = fRealTag (tvb, tree, offset, "real value: ");
4147 offset = fUnsignedTag (tvb, tree, offset, "enum value: ");
4150 offset = fUnsignedTag (tvb, tree, offset, "unsigned value: ");
4153 offset = fSignedTag (tvb, tree, offset, "signed value: ");
4156 offset = fBitStringTag (tvb, tree, offset, "bitstring value: ");
4159 offset = fNullTag(tvb, tree, offset, "null value: ");
4162 offset = fError (tvb,tree,offset);
4165 offset = fRealTag (tvb, tree, offset, "time change: ");
4167 case 10: /* any Value */
4168 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4169 offset = fAbstractSyntaxNType (tvb, tree, offset);
4170 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4175 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4178 offset = fEnumeratedTag (tvb, tree, offset,
4179 "status Flags: ", BACnetStatusFlags);
4190 fConfirmedEventNotificationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
4192 guint lastoffset = 0;
4193 guint8 tag_no, tag_info;
4196 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4197 lastoffset = offset;
4199 switch (fTagNo(tvb,offset)) {
4200 case 0: /* ProcessId */
4201 offset = fProcessId (tvb,tree,offset);
4203 case 1: /* initiating ObjectId */
4204 offset = fObjectIdentifier (tvb, tree, offset);
4206 case 2: /* event ObjectId */
4207 offset = fObjectIdentifier (tvb, tree, offset);
4209 case 3: /* time stamp */
4210 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4211 offset = fTimeStamp (tvb, tree, offset, NULL);
4212 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4214 case 4: /* notificationClass */
4215 offset = fUnsignedTag (tvb, tree, offset, "Notification Class: ");
4217 case 5: /* Priority */
4218 offset = fUnsignedTag (tvb, tree, offset, "Priority: ");
4220 case 6: /* EventType */
4221 offset = fEnumeratedTagSplit (tvb, tree, offset,
4222 "Event Type: ", BACnetEventType, 64);
4224 case 7: /* messageText */
4225 offset = fCharacterString (tvb, tree, offset, "message Text: ");
4227 case 8: /* NotifyType */
4228 offset = fEnumeratedTag (tvb, tree, offset,
4229 "Notify Type: ", BACnetNotifyType);
4231 case 9: /* ackRequired */
4232 offset = fBooleanTag (tvb, tree, offset, "ack Required: ");
4234 case 10: /* fromState */
4235 offset = fEnumeratedTagSplit (tvb, tree, offset,
4236 "from State: ", BACnetEventState, 64);
4238 case 11: /* toState */
4239 offset = fEnumeratedTagSplit (tvb, tree, offset,
4240 "to State: ", BACnetEventState, 64);
4242 case 12: /* NotificationParameters */
4243 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4244 offset = fNotificationParameters (tvb, tree, offset);
4245 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4255 fUnconfirmedEventNotificationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
4257 return fConfirmedEventNotificationRequest (tvb, tree, offset);
4261 fConfirmedCOVNotificationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
4263 guint lastoffset = 0;
4264 guint8 tag_no, tag_info;
4266 proto_tree *subtree = tree;
4269 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4270 lastoffset = offset;
4271 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4272 if (tag_is_closing(tag_info)) {
4273 offset += fTagHeaderTree (tvb, subtree, offset,
4274 &tag_no, &tag_info, &lvt);
4275 lastoffset = offset;
4281 case 0: /* ProcessId */
4282 offset = fProcessId (tvb,tree,offset);
4284 case 1: /* initiating DeviceId */
4285 offset = fObjectIdentifier (tvb, subtree, offset);
4287 case 2: /* monitored ObjectId */
4288 offset = fObjectIdentifier (tvb, subtree, offset);
4290 case 3: /* time remaining */
4291 offset = fTimeSpan (tvb, tree, offset, "Time remaining");
4293 case 4: /* List of Values */
4294 if (tag_is_opening(tag_info)) {
4295 tt = proto_tree_add_text(subtree, tvb, offset, 1, "list of Values");
4296 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
4297 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4298 offset = fBACnetPropertyValue (tvb, subtree, offset);
4311 fUnconfirmedCOVNotificationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
4313 return fConfirmedCOVNotificationRequest (tvb, tree, offset);
4317 fAcknowledgeAlarmRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
4319 guint lastoffset = 0;
4320 guint8 tag_no = 0, tag_info = 0;
4323 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4324 lastoffset = offset;
4325 switch (fTagNo(tvb, offset)) {
4326 case 0: /* acknowledgingProcessId */
4327 offset = fUnsignedTag (tvb, tree, offset, "acknowledging Process Id: ");
4329 case 1: /* eventObjectId */
4330 offset = fObjectIdentifier (tvb, tree, offset);
4332 case 2: /* eventStateAcknowledged */
4333 offset = fEnumeratedTagSplit (tvb, tree, offset,
4334 "event State Acknowledged: ", BACnetEventState, 64);
4336 case 3: /* timeStamp */
4337 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
4338 offset = fTimeStamp(tvb, tree, offset, NULL);
4339 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
4341 case 4: /* acknowledgementSource */
4342 offset = fCharacterString (tvb, tree, offset, "acknowledgement Source: ");
4344 case 5: /* timeOfAcknowledgement */
4345 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
4346 offset = fTimeStamp(tvb, tree, offset, "acknowledgement timestamp: ");
4347 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
4357 fGetAlarmSummaryAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
4359 guint lastoffset = 0;
4361 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4362 lastoffset = offset;
4363 offset = fApplicationTypes (tvb, tree, offset, "Object Identifier: ");
4364 offset = fApplicationTypesEnumeratedSplit (tvb, tree, offset,
4365 "alarm State: ", BACnetEventState, 64);
4366 offset = fApplicationTypesEnumerated (tvb, tree, offset,
4367 "acknowledged Transitions: ", BACnetEventTransitionBits);
4373 fGetEnrollmentSummaryRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
4375 guint lastoffset = 0;
4376 guint8 tag_no, tag_info;
4379 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4380 lastoffset = offset;
4381 switch (fTagNo(tvb, offset)) {
4382 case 0: /* acknowledgmentFilter */
4383 offset = fEnumeratedTag (tvb, tree, offset,
4384 "acknowledgment Filter: ", BACnetAcknowledgementFilter);
4386 case 1: /* eventObjectId - OPTIONAL */
4387 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4388 offset = fRecipientProcess (tvb, tree, offset);
4389 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4391 case 2: /* eventStateFilter */
4392 offset = fEnumeratedTag (tvb, tree, offset,
4393 "event State Filter: ", BACnetEventStateFilter);
4395 case 3: /* eventTypeFilter - OPTIONAL */
4396 offset = fEnumeratedTag (tvb, tree, offset,
4397 "event Type Filter: ", BACnetEventType);
4399 case 4: /* priorityFilter */
4400 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4401 offset = fUnsignedTag (tvb, tree, offset, "min Priority: ");
4402 offset = fUnsignedTag (tvb, tree, offset, "max Priority: ");
4403 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4405 case 5: /* notificationClassFilter - OPTIONAL */
4406 offset = fUnsignedTag (tvb, tree, offset, "notification Class Filter: ");
4416 fGetEnrollmentSummaryAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
4418 guint lastoffset = 0;
4420 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4421 lastoffset = offset;
4422 offset = fApplicationTypes (tvb, tree, offset, "Object Identifier: ");
4423 offset = fApplicationTypesEnumeratedSplit (tvb, tree, offset,
4424 "event Type: ", BACnetEventType, 64);
4425 offset = fApplicationTypesEnumerated (tvb, tree, offset,
4426 "event State: ", BACnetEventState);
4427 offset = fApplicationTypes (tvb, tree, offset, "Priority: ");
4428 offset = fApplicationTypes (tvb, tree, offset, "Notification Class: ");
4435 fGetEventInformationRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
4437 if (tvb_length_remaining(tvb, offset) > 0) {
4438 if (fTagNo(tvb, offset) == 0) {
4439 offset = fObjectIdentifier (tvb, tree, offset);
4446 flistOfEventSummaries (tvbuff_t *tvb, proto_tree *tree, guint offset)
4448 guint lastoffset = 0;
4449 guint8 tag_no, tag_info;
4451 proto_tree* subtree = tree;
4454 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4455 lastoffset = offset;
4456 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4457 /* we are finished here if we spot a closing tag */
4458 if (tag_is_closing(tag_info)) {
4462 case 0: /* ObjectId */
4463 offset = fObjectIdentifier (tvb, tree, offset);
4465 case 1: /* eventState */
4466 offset = fEnumeratedTag (tvb, tree, offset,
4467 "event State: ", BACnetEventState);
4469 case 2: /* acknowledgedTransitions */
4470 offset = fBitStringTagVS (tvb, tree, offset,
4471 "acknowledged Transitions: ", BACnetEventTransitionBits);
4473 case 3: /* eventTimeStamps */
4474 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventTimeStamps");
4476 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4478 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4479 offset = fTimeStamp (tvb, subtree, offset,"TO-OFFNORMAL timestamp: ");
4480 offset = fTimeStamp (tvb, subtree, offset,"TO-FAULT timestamp: ");
4481 offset = fTimeStamp (tvb, subtree, offset,"TO-NORMAL timestamp: ");
4482 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4484 case 4: /* notifyType */
4485 offset = fEnumeratedTag (tvb, tree, offset,
4486 "Notify Type: ", BACnetNotifyType);
4488 case 5: /* eventEnable */
4489 offset = fBitStringTagVS (tvb, tree, offset,
4490 "event Enable: ", BACnetEventTransitionBits);
4492 case 6: /* eventPriorities */
4493 ti = proto_tree_add_text(tree, tvb, offset, lvt, "eventPriorities");
4495 subtree = proto_item_add_subtree(ti, ett_bacapp_tag);
4497 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4498 offset = fUnsignedTag (tvb, subtree, offset, "TO-OFFNORMAL Priority: ");
4499 offset = fUnsignedTag (tvb, subtree, offset, "TO-FAULT Priority: ");
4500 offset = fUnsignedTag (tvb, subtree, offset, "TO-NORMAL Priority: ");
4501 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4511 fGetEventInformationACK (tvbuff_t *tvb, proto_tree *tree, guint offset)
4513 guint lastoffset = 0;
4514 guint8 tag_no, tag_info;
4517 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4518 lastoffset = offset;
4519 switch (fTagNo(tvb, offset)) {
4520 case 0: /* listOfEventSummaries */
4521 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4522 offset = flistOfEventSummaries (tvb, tree, offset);
4523 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
4525 case 1: /* moreEvents */
4526 offset = fBooleanTag (tvb, tree, offset, "more Events: ");
4536 fAddListElementRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
4538 guint lastoffset = 0;
4539 guint8 tag_no, tag_info;
4541 proto_tree *subtree = tree;
4544 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4545 lastoffset = offset;
4546 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4547 if (tag_is_closing(tag_info)) {
4548 offset += fTagHeaderTree (tvb, subtree, offset,
4549 &tag_no, &tag_info, &lvt);
4555 case 0: /* ObjectId */
4556 offset = fBACnetObjectPropertyReference (tvb, subtree, offset);
4558 case 3: /* listOfElements */
4559 if (tag_is_opening(tag_info)) {
4560 tt = proto_tree_add_text(subtree, tvb, offset, 1, "listOfElements");
4561 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
4562 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4563 offset = fAbstractSyntaxNType (tvb, subtree, offset);
4576 fDeleteObjectRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
4578 return fObjectIdentifier (tvb, tree, offset);
4582 fDeviceCommunicationControlRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
4584 guint lastoffset = 0;
4586 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4587 lastoffset = offset;
4589 switch (fTagNo(tvb, offset)) {
4590 case 0: /* timeDuration */
4591 offset = fUnsignedTag (tvb,tree,offset,"time Duration: ");
4593 case 1: /* enable-disable */
4594 offset = fEnumeratedTag (tvb, tree, offset, "enable-disable: ",
4595 BACnetEnableDisable);
4597 case 2: /* password - OPTIONAL */
4598 offset = fCharacterString (tvb, tree, offset, "Password: ");
4608 fReinitializeDeviceRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
4610 guint lastoffset = 0;
4612 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4613 lastoffset = offset;
4615 switch (fTagNo(tvb, offset)) {
4616 case 0: /* reinitializedStateOfDevice */
4617 offset = fEnumeratedTag (tvb, tree, offset,
4618 "reinitialized State Of Device: ",
4619 BACnetReinitializedStateOfDevice);
4621 case 1: /* password - OPTIONAL */
4622 offset = fCharacterString (tvb, tree, offset, "Password: ");
4632 fVtOpenRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
4634 offset = fApplicationTypesEnumerated (tvb, tree, offset,
4635 "vtClass: ", BACnetVTClass);
4636 return fApplicationTypes (tvb,tree,offset,"local VT Session ID: ");
4640 fVtOpenAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
4642 return fApplicationTypes (tvb,tree,offset,"remote VT Session ID: ");
4646 fVtCloseRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
4648 guint lastoffset = 0;
4650 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4651 lastoffset = offset;
4652 offset= fApplicationTypes (tvb,tree,offset,"remote VT Session ID: ");
4658 fVtDataRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
4660 offset= fApplicationTypes (tvb,tree,offset,"VT Session ID: ");
4661 offset = fApplicationTypes (tvb, tree, offset, "VT New Data: ");
4662 return fApplicationTypes (tvb,tree,offset,"VT Data Flag: ");;
4666 fVtDataAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
4668 guint lastoffset = 0;
4670 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4671 lastoffset = offset;
4673 switch (fTagNo(tvb,offset)) {
4674 case 0: /* BOOLEAN */
4675 offset = fBooleanTag (tvb, tree, offset, "all New Data Accepted: ");
4677 case 1: /* Unsigned OPTIONAL */
4678 offset = fUnsignedTag (tvb, tree, offset, "accepted Octet Count: ");
4688 fAuthenticateRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
4690 guint lastoffset = 0;
4692 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4693 lastoffset = offset;
4695 switch (fTagNo(tvb,offset)) {
4696 case 0: /* Unsigned32 */
4697 offset = fUnsignedTag (tvb, tree, offset, "pseudo Random Number: ");
4699 case 1: /* expected Invoke ID Unsigned8 OPTIONAL */
4700 proto_tree_add_item(tree, hf_bacapp_invoke_id, tvb, offset++, 1, TRUE);
4702 case 2: /* Chararacter String OPTIONAL */
4703 offset = fCharacterString (tvb, tree, offset, "operator Name: ");
4705 case 3: /* Chararacter String OPTIONAL */
4706 offset = fCharacterString (tvb, tree, offset, "operator Password: ");
4708 case 4: /* Boolean OPTIONAL */
4709 offset = fBooleanTag (tvb, tree, offset, "start Encyphered Session: ");
4719 fAuthenticateAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
4721 return fApplicationTypes (tvb, tree, offset, "modified Random Number: ");
4725 fRequestKeyRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
4727 offset = fObjectIdentifier (tvb, tree, offset); /* Requesting Device Identifier */
4728 offset = fAddress (tvb, tree, offset);
4729 offset = fObjectIdentifier (tvb, tree, offset); /* Remote Device Identifier */
4730 return fAddress (tvb, tree, offset);
4734 fRemoveListElementRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
4736 /* Same as AddListElement request after service choice */
4737 return fAddListElementRequest(tvb, tree, offset);
4741 fReadPropertyRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
4743 return fBACnetObjectPropertyReference(tvb, tree, offset);
4747 fReadPropertyAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
4749 guint lastoffset = 0;
4750 guint8 tag_no, tag_info;
4752 proto_tree *subtree = tree;
4755 /* set the optional global properties to indicate not-used */
4756 propertyArrayIndex = -1;
4757 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4758 lastoffset = offset;
4759 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4760 if (tag_is_closing(tag_info)) {
4761 offset += fTagHeaderTree (tvb, subtree, offset,
4762 &tag_no, &tag_info, &lvt);
4767 case 0: /* objectIdentifier */
4768 offset = fObjectIdentifier (tvb, subtree, offset);
4770 case 1: /* propertyIdentifier */
4771 offset = fPropertyIdentifier (tvb, subtree, offset);
4773 case 2: /* propertyArrayIndex */
4774 offset = fPropertyArrayIndex (tvb, subtree, offset);
4776 case 3: /* propertyValue */
4777 if (tag_is_opening(tag_info)) {
4778 tt = proto_tree_add_text(subtree, tvb, offset, 1, "propertyValue");
4779 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
4780 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4781 offset = fAbstractSyntaxNType (tvb, subtree, offset);
4794 fWritePropertyRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
4796 guint lastoffset = 0;
4797 guint8 tag_no, tag_info;
4799 proto_tree *subtree = tree;
4802 /* set the optional global properties to indicate not-used */
4803 propertyArrayIndex = -1;
4804 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4805 lastoffset = offset;
4806 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4807 if (tag_is_closing(tag_info)) {
4808 offset += fTagHeaderTree (tvb, subtree, offset,
4809 &tag_no, &tag_info, &lvt);
4815 case 0: /* objectIdentifier */
4816 offset = fObjectIdentifier (tvb, subtree, offset);
4818 case 1: /* propertyIdentifier */
4819 offset = fPropertyIdentifier (tvb, subtree, offset);
4821 case 2: /* propertyArrayIndex */
4822 offset = fPropertyArrayIndex (tvb, subtree, offset);
4824 case 3: /* propertyValue */
4825 if (tag_is_opening(tag_info)) {
4826 tt = proto_tree_add_text(subtree, tvb, offset, 1, "propertyValue");
4827 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
4828 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4829 offset = fAbstractSyntaxNType (tvb, subtree, offset);
4834 case 4: /* Priority (only used for write) */
4835 offset = fUnsignedTag (tvb, subtree, offset, "Priority: ");
4845 fWriteAccessSpecification (tvbuff_t *tvb, proto_tree *subtree, guint offset)
4847 guint lastoffset = 0;
4848 guint8 tag_no, tag_info;
4851 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4852 lastoffset = offset;
4853 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4854 if (tag_is_closing(tag_info)) {
4855 offset += fTagHeaderTree (tvb, subtree, offset,
4856 &tag_no, &tag_info, &lvt);
4861 case 0: /* objectIdentifier */
4862 offset = fObjectIdentifier (tvb, subtree, offset);
4864 case 1: /* listOfPropertyValues */
4865 if (tag_is_opening(tag_info)) {
4866 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4867 offset = fBACnetPropertyValue (tvb, subtree, offset);
4880 fWritePropertyMultipleRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
4882 if (offset >= tvb_reported_length(tvb))
4885 return fWriteAccessSpecification (tvb, tree, offset);
4889 fPropertyReference (tvbuff_t *tvb, proto_tree *tree, guint offset, guint8 tagoffset, guint8 list)
4891 guint lastoffset = 0;
4892 guint8 tag_no, tag_info;
4895 /* set the optional global properties to indicate not-used */
4896 propertyArrayIndex = -1;
4897 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4898 lastoffset = offset;
4899 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4900 if (tag_is_closing(tag_info)) { /* closing Tag, but not for me */
4902 } else if (tag_is_opening(tag_info)) { /* opening Tag, but not for me */
4905 switch (tag_no-tagoffset) {
4906 case 0: /* PropertyIdentifier */
4907 offset = fPropertyIdentifier (tvb, tree, offset);
4909 case 1: /* propertyArrayIndex */
4910 offset = fPropertyArrayIndex (tvb, tree, offset);
4911 if (list != 0) break; /* Continue decoding if this may be a list */
4913 lastoffset = offset; /* Set loop end condition */
4921 fBACnetPropertyReference (tvbuff_t *tvb, proto_tree *tree, guint offset, guint8 list)
4923 return fPropertyReference(tvb, tree, offset, 0, list);
4927 fBACnetObjectPropertyReference (tvbuff_t *tvb, proto_tree *tree, guint offset)
4929 guint lastoffset = 0;
4931 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4932 lastoffset = offset;
4934 switch (fTagNo(tvb,offset)) {
4935 case 0: /* ObjectIdentifier */
4936 offset = fObjectIdentifier (tvb, tree, offset);
4938 case 1: /* PropertyIdentifier and propertyArrayIndex */
4939 offset = fPropertyReference (tvb, tree, offset, 1, 0);
4941 lastoffset = offset; /* Set loop end condition */
4950 fObjectPropertyValue (tvbuff_t *tvb, proto_tree *tree, guint offset)
4952 guint lastoffset = 0;
4953 guint8 tag_no, tag_info;
4955 proto_tree* subtree = tree;
4958 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
4959 lastoffset = offset;
4960 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
4961 if (tag_is_closing(tag_info)) {
4962 offset += fTagHeaderTree (tvb, subtree, offset,
4963 &tag_no, &tag_info, &lvt);
4967 case 0: /* ObjectIdentifier */
4968 offset = fObjectIdentifier (tvb, subtree, offset);
4970 case 1: /* PropertyIdentifier */
4971 offset = fPropertyIdentifier (tvb, subtree, offset);
4973 case 2: /* propertyArrayIndex */
4974 offset = fUnsignedTag (tvb, subtree, offset, "property Array Index: ");
4977 if (tag_is_opening(tag_info)) {
4978 tt = proto_tree_add_text(subtree, tvb, offset, 1, "propertyValue");
4979 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
4980 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
4981 offset = fAbstractSyntaxNType (tvb, subtree, offset);
4986 case 4: /* Priority */
4987 offset = fUnsignedTag (tvb, subtree, offset, "Priority: ");
4998 fPriorityArray (tvbuff_t *tvb, proto_tree *tree, guint offset)
5000 char i = 1, ar[256];
5001 guint lastoffset = 0;
5003 if (propertyArrayIndex > 0) {
5004 /* BACnetARRAY index 0 refers to the length
5005 of the array, not the elements of the array.
5006 BACnetARRAY index -1 is our internal flag that
5007 the optional index was not used.
5008 BACnetARRAY refers to this as all elements of the array.
5009 If the optional index is specified for a BACnetARRAY,
5010 then that specific array element is referenced. */
5011 i = propertyArrayIndex;
5013 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
5014 /* exit loop if nothing happens inside */
5015 lastoffset = offset;
5016 g_snprintf (ar, sizeof(ar), "%s[%d]: ",
5017 val_to_split_str(87 , 512,
5018 BACnetPropertyIdentifier,
5019 ASHRAE_Reserved_Fmt,
5020 Vendor_Proprietary_Fmt),
5022 /* DMR Should be fAbstractNSyntax, but that's where we came from! */
5023 offset = fApplicationTypes(tvb, tree, offset, ar);
5024 /* there are only 16 priority array elements */
5034 fDeviceObjectReference (tvbuff_t *tvb, proto_tree *tree, guint offset)
5036 guint lastoffset = 0;
5038 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
5039 lastoffset = offset;
5041 switch (fTagNo(tvb,offset)) {
5042 case 0: /* deviceIdentifier - OPTIONAL */
5043 offset = fObjectIdentifier (tvb, tree, offset);
5045 case 1: /* ObjectIdentifier */
5046 offset = fObjectIdentifier (tvb, tree, offset);
5056 fSpecialEvent (tvbuff_t *tvb, proto_tree *subtree, guint offset)
5058 guint8 tag_no, tag_info;
5060 guint lastoffset = 0;
5062 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
5063 lastoffset = offset;
5064 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5065 if (tag_is_closing(tag_info)) {
5070 case 0: /* calendaryEntry */
5071 if (tag_is_opening(tag_info))
5073 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5074 offset = fCalendaryEntry (tvb, subtree, offset);
5075 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5078 case 1: /* calendarReference */
5079 offset = fObjectIdentifier (tvb, subtree, offset);
5081 case 2: /* list of BACnetTimeValue */
5082 if (tag_is_opening(tag_info)) {
5083 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5084 offset = fTimeValue (tvb, subtree, offset);
5085 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5090 case 3: /* eventPriority */
5091 offset = fUnsignedTag (tvb, subtree, offset, "event priority: ");
5101 fSelectionCriteria (tvbuff_t *tvb, proto_tree *tree, guint offset)
5103 guint lastoffset = 0;
5104 guint8 tag_no, tag_info;
5107 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
5108 lastoffset = offset;
5109 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5110 if (tag_is_closing(tag_info)) { /* stop when we hit outer closing tag */
5114 switch (fTagNo(tvb,offset)) {
5115 case 0: /* propertyIdentifier */
5116 offset = fPropertyIdentifier (tvb, tree, offset);
5118 case 1: /* propertyArrayIndex */
5119 offset = fPropertyArrayIndex (tvb, tree, offset);
5121 case 2: /* relationSpecifier */
5122 offset = fEnumeratedTag (tvb, tree, offset,
5123 "relation Specifier: ", BACnetRelationSpecifier);
5125 case 3: /* comparisonValue */
5126 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
5127 offset = fAbstractSyntaxNType (tvb, tree, offset);
5128 offset += fTagHeaderTree (tvb, tree, offset, &tag_no, &tag_info, &lvt);
5138 fObjectSelectionCriteria (tvbuff_t *tvb, proto_tree *subtree, guint offset)
5140 guint lastoffset = 0;
5141 guint8 tag_no, tag_info;
5144 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
5145 lastoffset = offset;
5146 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5147 if (tag_is_closing(tag_info)) { /* stop when we hit outer closing tag */
5152 case 0: /* selectionLogic */
5153 offset = fEnumeratedTag (tvb, subtree, offset,
5154 "selection Logic: ", BACnetSelectionLogic);
5156 case 1: /* listOfSelectionCriteria */
5157 if (tag_is_opening(tag_info)) {
5158 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5159 offset = fSelectionCriteria (tvb, subtree, offset);
5160 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5174 fReadPropertyConditionalRequest(tvbuff_t *tvb, proto_tree *subtree, guint offset)
5176 guint lastoffset = 0;
5177 guint8 tag_no, tag_info;
5180 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
5181 lastoffset = offset;
5182 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5184 if (tag_is_opening(tag_info) && tag_no < 2) {
5185 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5187 case 0: /* objectSelectionCriteria */
5188 offset = fObjectSelectionCriteria (tvb, subtree, offset);
5190 case 1: /* listOfPropertyReferences */
5191 offset = fBACnetPropertyReference (tvb, subtree, offset, 1);
5196 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5203 fReadAccessSpecification (tvbuff_t *tvb, proto_tree *tree, guint offset)
5205 guint lastoffset = 0;
5206 guint8 tag_no, tag_info;
5209 proto_tree *subtree = tree;
5211 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
5212 lastoffset = offset;
5213 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5215 case 0: /* objectIdentifier */
5216 offset = fObjectIdentifier (tvb, subtree, offset);
5218 case 1: /* listOfPropertyReferences */
5219 if (tag_is_opening(tag_info)) {
5220 tt = proto_tree_add_text(subtree, tvb, offset, 1, "listOfPropertyReferences");
5221 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5222 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5223 offset = fBACnetPropertyReference (tvb, subtree, offset, 1);
5224 } else if (tag_is_closing(tag_info)) {
5225 offset += fTagHeaderTree (tvb, subtree, offset,
5226 &tag_no, &tag_info, &lvt);
5229 /* error condition: let caller handle */
5241 fReadAccessResult (tvbuff_t *tvb, proto_tree *tree, guint offset)
5243 guint lastoffset = 0;
5247 proto_tree *subtree = tree;
5250 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
5251 lastoffset = offset;
5252 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5253 if (tag_is_closing(tag_info)) {
5254 offset += fTagHeaderTree (tvb, subtree, offset,
5255 &tag_no, &tag_info, &lvt);
5256 if ((tag_no == 4 || tag_no == 5) && (subtree != tree)) subtree = subtree->parent; /* Value and error have extra subtree */
5261 case 0: /* objectSpecifier */
5262 offset = fObjectIdentifier (tvb, subtree, offset);
5264 case 1: /* list of Results */
5265 if (tag_is_opening(tag_info)) {
5266 tt = proto_tree_add_text(subtree, tvb, offset, 1, "listOfResults");
5267 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5268 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5273 case 2: /* propertyIdentifier */
5274 offset = fPropertyValue(tvb, subtree, offset, 2);
5276 case 5: /* propertyAccessError */
5277 if (tag_is_opening(tag_info)) {
5278 tt = proto_tree_add_text(subtree, tvb, offset, 1, "propertyAccessError");
5279 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5280 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5281 /* Error Code follows */
5282 offset = fError(tvb, subtree, offset);
5296 fReadPropertyConditionalAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
5298 /* listOfReadAccessResults */
5299 return fReadAccessResult (tvb, tree, offset);
5304 fCreateObjectRequest(tvbuff_t *tvb, proto_tree *subtree, guint offset)
5306 guint lastoffset = 0;
5307 guint8 tag_no, tag_info;
5310 while ((tvb_length_remaining(tvb, offset) > 0) && (offset > lastoffset)) { /* exit loop if nothing happens inside */
5311 lastoffset = offset;
5312 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5316 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5318 case 0: /* objectSpecifier */
5319 switch (fTagNo(tvb, offset)) { /* choice of objectType or objectIdentifier */
5320 case 0: /* objectType */
5321 offset = fEnumeratedTagSplit (tvb, subtree, offset, "Object Type: ", BACnetObjectType, 128);
5323 case 1: /* objectIdentifier */
5324 offset = fObjectIdentifier (tvb, subtree, offset);
5330 case 1: /* propertyValue */
5331 if (tag_is_opening(tag_info)) {
5332 offset = fBACnetPropertyValue (tvb, subtree, offset);
5340 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5347 fCreateObjectAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
5349 return fObjectIdentifier (tvb, tree, offset);
5353 fReadRangeRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
5355 guint8 tag_no, tag_info;
5357 proto_tree *subtree = tree;
5360 offset = fBACnetObjectPropertyReference(tvb, subtree, offset);
5362 if (tvb_length_remaining(tvb, offset) > 0) {
5363 /* optional range choice */
5364 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5365 if (tag_is_opening(tag_info)) {
5366 tt = proto_tree_add_text(subtree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetReadRangeOptions, "unknown range option"));
5367 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5368 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5370 case 3: /* range byPosition */
5371 case 6: /* range bySequenceNumber, 2004 spec */
5372 offset = fApplicationTypes (tvb, subtree, offset, "reference Index: ");
5373 offset = fApplicationTypes (tvb, subtree, offset, "reference Count: ");
5375 case 4: /* range byTime - deprecated in 2004 */
5376 case 7: /* 2004 spec */
5377 offset = fDateTime(tvb, subtree, offset, "reference Date/Time: ");
5378 offset = fApplicationTypes (tvb, subtree, offset, "reference Count: ");
5380 case 5: /* range timeRange - deprecated in 2004 */
5381 offset = fDateTime(tvb, subtree, offset, "beginning Time: ");
5382 offset = fDateTime(tvb, subtree, offset, "ending Time: ");
5387 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5394 fReadRangeAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
5396 guint8 tag_no, tag_info;
5398 proto_tree *subtree = tree;
5401 /* set the optional global properties to indicate not-used */
5402 propertyArrayIndex = -1;
5403 /* objectIdentifier, propertyIdentifier, and
5404 OPTIONAL propertyArrayIndex */
5405 offset = fBACnetObjectPropertyReference(tvb, subtree, offset);
5406 /* resultFlags => BACnetResultFlags ::= BIT STRING */
5407 offset = fBitStringTagVS (tvb, tree, offset,
5411 offset = fUnsignedTag (tvb, subtree, offset, "item Count: ");
5413 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5414 if (tag_is_opening(tag_info)) {
5415 tt = proto_tree_add_text(subtree, tvb, offset, 1, "itemData");
5416 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5417 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5418 offset = fAbstractSyntaxNType (tvb, subtree, offset);
5419 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5421 /* firstSequenceNumber - OPTIONAL */
5422 if (tvb_length_remaining(tvb, offset) > 0) {
5423 offset = fUnsignedTag (tvb, subtree, offset, "first Sequence Number: ");
5429 static guint fAccessMethod(tvbuff_t *tvb, proto_tree *tree, guint offset)
5431 guint lastoffset = 0;
5433 guint8 tag_no, tag_info;
5435 proto_tree* subtree = NULL;
5437 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5439 if (tag_is_opening(tag_info))
5441 tt = proto_tree_add_text(tree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetFileAccessOption, "invalid access method"));
5442 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5443 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5444 offset = fApplicationTypes (tvb, subtree, offset, val_to_str(tag_no, BACnetFileStartOption, "invalid option"));
5445 offset = fApplicationTypes (tvb, subtree, offset, val_to_str(tag_no, BACnetFileWriteInfo, "unknown option"));
5449 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset))
5450 { /* exit loop if nothing happens inside */
5451 lastoffset = offset;
5452 offset = fApplicationTypes (tvb, subtree, offset, "Record Data: ");
5456 if ((bacapp_flags & BACAPP_MORE_SEGMENTS) == 0)
5458 /* More Flag is not set, so we can look for closing tag in this segment */
5459 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5460 if (tag_is_closing(tag_info)) {
5461 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5469 fAtomicReadFileRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
5471 guint8 tag_no, tag_info;
5473 proto_tree *subtree = tree;
5476 offset = fObjectIdentifier (tvb, tree, offset);
5478 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5480 if (tag_is_opening(tag_info))
5482 tt = proto_tree_add_text(subtree, tvb, offset, 1, "%s", val_to_str(tag_no, BACnetFileAccessOption, "unknown access method"));
5483 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5484 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5485 offset = fSignedTag (tvb, subtree, offset, val_to_str(tag_no, BACnetFileStartOption, "unknown option"));
5486 offset = fUnsignedTag (tvb, subtree, offset, val_to_str(tag_no, BACnetFileRequestCount, "unknown option"));
5487 offset += fTagHeaderTree (tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5493 fAtomicWriteFileRequest(tvbuff_t *tvb, proto_tree *tree, guint offset)
5496 offset = fObjectIdentifier (tvb, tree, offset); /* file Identifier */
5497 offset = fAccessMethod(tvb, tree, offset);
5503 fAtomicWriteFileAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
5505 guint tag_no = fTagNo(tvb, offset);
5506 return fSignedTag (tvb, tree, offset, val_to_str(tag_no, BACnetFileStartOption, "unknown option"));
5510 fAtomicReadFileAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
5512 offset = fApplicationTypes (tvb, tree, offset, "End Of File: ");
5513 offset = fAccessMethod(tvb, tree, offset);
5519 fReadPropertyMultipleRequest(tvbuff_t *tvb, proto_tree *subtree, guint offset)
5521 return fReadAccessSpecification (tvb,subtree,offset);
5525 fReadPropertyMultipleAck (tvbuff_t *tvb, proto_tree *tree, guint offset)
5527 return fReadAccessResult (tvb,tree,offset);
5531 fConfirmedServiceRequest (tvbuff_t *tvb, proto_tree *tree, guint offset, gint service_choice)
5533 if (tvb_length_remaining(tvb,offset) <= 0)
5536 switch (service_choice) {
5537 case 0: /* acknowledgeAlarm */
5538 offset = fAcknowledgeAlarmRequest (tvb, tree, offset);
5540 case 1: /* confirmedCOVNotification */
5541 offset = fConfirmedCOVNotificationRequest (tvb, tree, offset);
5543 case 2: /* confirmedEventNotification */
5544 offset = fConfirmedEventNotificationRequest (tvb, tree, offset);
5546 case 3: /* confirmedGetAlarmSummary conveys no parameters */
5548 case 4: /* getEnrollmentSummaryRequest */
5549 offset = fGetEnrollmentSummaryRequest (tvb, tree, offset);
5551 case 5: /* subscribeCOVRequest */
5552 offset = fSubscribeCOVRequest(tvb, tree, offset);
5554 case 6: /* atomicReadFile-Request */
5555 offset = fAtomicReadFileRequest(tvb, tree, offset);
5557 case 7: /* atomicWriteFile-Request */
5558 offset = fAtomicWriteFileRequest(tvb, tree, offset);
5560 case 8: /* AddListElement-Request */
5561 offset = fAddListElementRequest(tvb, tree, offset);
5563 case 9: /* removeListElement-Request */
5564 offset = fRemoveListElementRequest(tvb, tree, offset);
5566 case 10: /* createObjectRequest */
5567 offset = fCreateObjectRequest(tvb, tree, offset);
5569 case 11: /* deleteObject */
5570 offset = fDeleteObjectRequest(tvb, tree, offset);
5573 offset = fReadPropertyRequest(tvb, tree, offset);
5576 offset = fReadPropertyConditionalRequest(tvb, tree, offset);
5579 offset = fReadPropertyMultipleRequest(tvb, tree, offset);
5582 offset = fWritePropertyRequest(tvb, tree, offset);
5585 offset = fWritePropertyMultipleRequest(tvb, tree, offset);
5588 offset = fDeviceCommunicationControlRequest(tvb, tree, offset);
5591 offset = fConfirmedPrivateTransferRequest(tvb, tree, offset);
5594 offset = fConfirmedTextMessageRequest(tvb, tree, offset);
5597 offset = fReinitializeDeviceRequest(tvb, tree, offset);
5600 offset = fVtOpenRequest(tvb, tree, offset);
5603 offset = fVtCloseRequest (tvb, tree, offset);
5606 offset = fVtDataRequest (tvb, tree, offset);
5609 offset = fAuthenticateRequest (tvb, tree, offset);
5612 offset = fRequestKeyRequest (tvb, tree, offset);
5615 offset = fReadRangeRequest (tvb, tree, offset);
5618 offset = fLifeSafetyOperationRequest(tvb, tree, offset, NULL);
5621 offset = fSubscribeCOVPropertyRequest(tvb, tree, offset);
5624 offset = fGetEventInformationRequest (tvb, tree, offset);
5633 fConfirmedServiceAck (tvbuff_t *tvb, proto_tree *tree, guint offset, gint service_choice)
5635 if (tvb_length_remaining(tvb,offset) <= 0)
5638 switch (service_choice) {
5639 case 3: /* confirmedEventNotificationAck */
5640 offset = fGetAlarmSummaryAck (tvb, tree, offset);
5642 case 4: /* getEnrollmentSummaryAck */
5643 offset = fGetEnrollmentSummaryAck (tvb, tree, offset);
5645 case 6: /* atomicReadFile */
5646 offset = fAtomicReadFileAck (tvb, tree, offset);
5648 case 7: /* atomicReadFileAck */
5649 offset = fAtomicWriteFileAck (tvb, tree, offset);
5651 case 10: /* createObject */
5652 offset = fCreateObjectAck (tvb, tree, offset);
5655 offset = fReadPropertyAck (tvb, tree, offset);
5658 offset = fReadPropertyConditionalAck (tvb, tree, offset);
5661 offset = fReadPropertyMultipleAck (tvb, tree, offset);
5664 offset = fConfirmedPrivateTransferAck(tvb, tree, offset);
5667 offset = fVtOpenAck (tvb, tree, offset);
5670 offset = fVtDataAck (tvb, tree, offset);
5673 offset = fAuthenticateAck (tvb, tree, offset);
5676 offset = fReadRangeAck (tvb, tree, offset);
5679 offset = fGetEventInformationACK (tvb, tree, offset);
5688 fIAmRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
5690 /* BACnetObjectIdentifier */
5691 offset = fApplicationTypes (tvb, tree, offset, "BACnet Object Identifier: ");
5693 /* MaxAPDULengthAccepted */
5694 offset = fApplicationTypes (tvb, tree, offset, "Maximum ADPU Length Accepted: ");
5696 /* segmentationSupported */
5697 offset = fApplicationTypesEnumerated (tvb, tree, offset,
5698 "Segmentation Supported: ", BACnetSegmentation);
5701 return fVendorIdentifier (tvb, tree, offset);
5705 fIHaveRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
5707 /* BACnetDeviceIdentifier */
5708 offset = fApplicationTypes (tvb, tree, offset, "Device Identifier: ");
5710 /* BACnetObjectIdentifier */
5711 offset = fApplicationTypes (tvb, tree, offset, "Object Identifier: ");
5714 return fApplicationTypes (tvb, tree, offset, "Object Name: ");
5719 fWhoIsRequest (tvbuff_t *tvb, proto_tree *tree, guint offset)
5721 guint lastoffset = 0;
5723 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
5724 lastoffset = offset;
5725 switch (fTagNo(tvb, offset)) {
5726 case 0: /* DeviceInstanceRangeLowLimit Optional */
5727 offset = fUnsignedTag (tvb, tree, offset, "Device Instance Range Low Limit: ");
5729 case 1: /* DeviceInstanceRangeHighLimit Optional but required if DeviceInstanceRangeLowLimit is there */
5730 offset = fUnsignedTag (tvb, tree, offset, "Device Instance Range High Limit: ");
5740 fUnconfirmedServiceRequest (tvbuff_t *tvb, proto_tree *tree, guint offset, gint service_choice)
5742 if (tvb_length_remaining(tvb,offset) <= 0)
5745 switch (service_choice) {
5746 case 0: /* I-Am-Request */
5747 offset = fIAmRequest (tvb, tree, offset);
5749 case 1: /* i-Have Request */
5750 offset = fIHaveRequest (tvb, tree, offset);
5752 case 2: /* unconfirmedCOVNotification */
5753 offset = fUnconfirmedCOVNotificationRequest (tvb, tree, offset);
5755 case 3: /* unconfirmedEventNotification */
5756 offset = fUnconfirmedEventNotificationRequest (tvb, tree, offset);
5758 case 4: /* unconfirmedPrivateTransfer */
5759 offset = fUnconfirmedPrivateTransferRequest(tvb, tree, offset);
5761 case 5: /* unconfirmedTextMessage */
5762 offset = fUnconfirmedTextMessageRequest(tvb, tree, offset);
5764 case 6: /* timeSynchronization */
5765 offset = fTimeSynchronizationRequest (tvb, tree, offset);
5767 case 7: /* who-Has */
5768 offset = fWhoHas (tvb, tree, offset);
5770 case 8: /* who-Is */
5771 offset = fWhoIsRequest (tvb, tree, offset);
5773 case 9: /* utcTimeSynchronization */
5774 offset = fUTCTimeSynchronizationRequest (tvb, tree, offset);
5783 fStartConfirmed(tvbuff_t *tvb, proto_tree *bacapp_tree, guint offset, guint8 ack,
5784 gint *svc, proto_item **tt)
5787 proto_tree *bacapp_tree_control;
5788 gint tmp, bacapp_type;
5792 tmp = (gint) tvb_get_guint8(tvb, offset);
5793 bacapp_type = (tmp >> 4) & 0x0f;
5794 bacapp_flags = tmp & 0x0f;
5799 *svc = (gint) tvb_get_guint8(tvb, offset+extra);
5800 if (bacapp_flags & 0x08)
5801 *svc = (gint) tvb_get_guint8(tvb, offset+extra+2);
5803 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, TRUE);
5804 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_pduflags, tvb, offset, 1, TRUE);
5805 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp_control);
5807 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SEG, tvb, offset, 1, TRUE);
5808 proto_tree_add_item(bacapp_tree_control, hf_bacapp_MOR, tvb, offset, 1, TRUE);
5809 if (ack == 0) /* The following are for ConfirmedRequest, not Complex ack */
5811 proto_tree_add_item(bacapp_tree_control, hf_bacapp_SA, tvb, offset++, 1, TRUE);
5812 proto_tree_add_item(bacapp_tree, hf_bacapp_response_segments, tvb,
5814 proto_tree_add_item(bacapp_tree, hf_bacapp_max_adpu_size, tvb,
5818 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb, offset++, 1, TRUE);
5819 if (bacapp_flags & 0x08) {
5820 bacapp_seq = tvb_get_guint8(tvb, offset);
5821 proto_tree_add_item(bacapp_tree_control, hf_bacapp_sequence_number, tvb,
5823 proto_tree_add_item(bacapp_tree_control, hf_bacapp_window_size, tvb,
5826 *tt = proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
5832 fConfirmedRequestPDU(tvbuff_t *tvb, proto_tree *bacapp_tree, guint offset)
5833 { /* BACnet-Confirmed-Request */
5834 /* ASHRAE 135-2001 20.1.2 */
5838 offset = fStartConfirmed(tvb, bacapp_tree, offset, 0, &svc, &tt);
5839 if (bacapp_seq > 0) /* Can't handle continuation segments, so just treat as data */
5841 proto_tree_add_text(bacapp_tree, tvb, offset, 0, "(continuation)");
5846 /* Service Request follows... Variable Encoding 20.2ff */
5847 return fConfirmedServiceRequest (tvb, bacapp_tree, offset, svc);
5852 fUnconfirmedRequestPDU(tvbuff_t *tvb, proto_tree *bacapp_tree, guint offset)
5853 { /* BACnet-Unconfirmed-Request-PDU */
5854 /* ASHRAE 135-2001 20.1.3 */
5858 proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, TRUE);
5860 tmp = tvb_get_guint8(tvb, offset);
5861 proto_tree_add_item(bacapp_tree, hf_bacapp_uservice, tvb,
5863 /* Service Request follows... Variable Encoding 20.2ff */
5864 return fUnconfirmedServiceRequest (tvb, bacapp_tree, offset, tmp);
5868 fSimpleAckPDU(tvbuff_t *tvb, proto_tree *bacapp_tree, guint offset)
5869 { /* BACnet-Simple-Ack-PDU */
5870 /* ASHRAE 135-2001 20.1.4 */
5874 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, TRUE);
5876 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
5878 proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
5885 fComplexAckPDU(tvbuff_t *tvb, proto_tree *bacapp_tree, guint offset)
5886 { /* BACnet-Complex-Ack-PDU */
5887 /* ASHRAE 135-2001 20.1.5 */
5891 offset = fStartConfirmed(tvb, bacapp_tree, offset, 1, &svc, &tt);
5893 if (bacapp_seq > 0) /* Can't handle continuation segments, so just treat as data */
5895 proto_tree_add_text(bacapp_tree, tvb, offset, 0, "(continuation)");
5900 /* Service ACK follows... */
5901 return fConfirmedServiceAck (tvb, bacapp_tree, offset, svc);
5907 fSegmentAckPDU(tvbuff_t *tvb, proto_tree *bacapp_tree, guint offset)
5908 { /* BACnet-SegmentAck-PDU */
5909 /* ASHRAE 135-2001 20.1.6 */
5912 proto_tree *bacapp_tree_control;
5914 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, TRUE);
5915 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
5917 proto_tree_add_item(bacapp_tree, hf_bacapp_NAK, tvb, offset, 1, TRUE);
5918 proto_tree_add_item(bacapp_tree, hf_bacapp_SRV, tvb, offset++, 1, TRUE);
5919 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
5921 proto_tree_add_item(bacapp_tree, hf_bacapp_sequence_number, tvb,
5923 proto_tree_add_item(bacapp_tree, hf_bacapp_window_size, tvb,
5928 static guint fContextTaggedError(tvbuff_t *tvb, proto_tree *tree, guint offset)
5930 guint8 tag_info = 0;
5931 guint8 parsed_tag = 0;
5933 offset += fTagHeaderTree(tvb, tree, offset, &parsed_tag, &tag_info, &lvt);
5934 offset = fError(tvb, tree, offset);
5935 return offset + fTagHeaderTree(tvb, tree, offset, &parsed_tag, &tag_info, &lvt);
5939 fConfirmedPrivateTransferError(tvbuff_t *tvb, proto_tree *tree, guint offset)
5941 guint lastoffset = 0;
5942 guint8 tag_no = 0, tag_info = 0;
5944 proto_tree *subtree = tree;
5947 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) {
5948 /* exit loop if nothing happens inside */
5949 lastoffset = offset;
5950 fTagHeader (tvb, offset, &tag_no, &tag_info, &lvt);
5952 case 0: /* errorType */
5953 offset = fContextTaggedError(tvb, subtree, offset);
5955 case 1: /* vendorID */
5956 offset = fVendorIdentifier (tvb, subtree, offset);
5958 case 2: /* serviceNumber */
5959 offset = fUnsignedTag (tvb, subtree, offset, "service Number: ");
5961 case 3: /* errorParameters */
5962 if (tag_is_opening(tag_info)) {
5963 tt = proto_tree_add_text(subtree, tvb, offset, 1,
5964 "error Parameters");
5965 subtree = proto_item_add_subtree(tt, ett_bacapp_value);
5966 propertyIdentifier = -1;
5967 offset += fTagHeaderTree(tvb, subtree, offset, &tag_no, &tag_info, &lvt);
5968 offset = fAbstractSyntaxNType (tvb, subtree, offset);
5969 } else if (tag_is_closing(tag_info)) {
5970 offset += fTagHeaderTree (tvb, subtree, offset,
5971 &tag_no, &tag_info, &lvt);
5974 /* error condition: let caller handle */
5986 fCreateObjectError(tvbuff_t *tvb, proto_tree *tree, guint offset)
5988 guint lastoffset = 0;
5990 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
5991 lastoffset = offset;
5992 switch (fTagNo(tvb, offset)) {
5993 case 0: /* errorType */
5994 offset = fContextTaggedError(tvb,tree,offset);
5996 case 1: /* firstFailedElementNumber */
5997 offset = fUnsignedTag (tvb,tree,offset,"first failed element number: ");
6007 fChangeListError(tvbuff_t *tvb, proto_tree *tree, guint offset)
6009 /* Identical to CreateObjectError */
6010 return fCreateObjectError(tvb, tree, offset);
6014 fVTCloseError(tvbuff_t *tvb, proto_tree *tree, guint offset)
6016 guint8 tag_no = 0, tag_info = 0;
6019 if (fTagNo(tvb, offset) == 0)
6022 offset = fContextTaggedError(tvb,tree,offset);
6023 if (fTagNo(tvb, offset) == 1)
6025 /* listOfVTSessionIdentifiers [OPTIONAL] */
6026 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6027 offset = fVtCloseRequest (tvb, tree, offset);
6028 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6031 /* should report bad packet if initial tag wasn't 0 */
6036 fWritePropertyMultipleError(tvbuff_t *tvb, proto_tree *tree, guint offset)
6038 guint lastoffset = 0;
6039 guint8 tag_no = 0, tag_info = 0;
6042 while ((tvb_length_remaining(tvb, offset) > 0)&&(offset>lastoffset)) { /* exit loop if nothing happens inside */
6043 lastoffset = offset;
6044 switch (fTagNo(tvb, offset)) {
6045 case 0: /* errorType */
6046 offset = fContextTaggedError(tvb,tree,offset);
6048 case 1: /* firstFailedWriteAttempt */
6049 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6050 offset = fBACnetObjectPropertyReference(tvb, tree, offset);
6051 offset += fTagHeaderTree(tvb, tree, offset, &tag_no, &tag_info, &lvt);
6061 fError (tvbuff_t *tvb, proto_tree *tree, guint offset)
6063 offset = fApplicationTypesEnumeratedSplit (tvb, tree, offset,
6064 "error Class: ", BACnetErrorClass, 64);
6065 return fApplicationTypesEnumeratedSplit (tvb, tree, offset,
6066 "error Code: ", BACnetErrorCode, 256);
6070 fBACnetError (tvbuff_t *tvb, proto_tree *tree, guint offset, guint service)
6073 case 8: /* no break here !!!! */
6075 offset = fChangeListError (tvb, tree, offset);
6078 offset = fCreateObjectError (tvb,tree,offset);
6081 offset = fWritePropertyMultipleError (tvb,tree,offset);
6084 offset = fConfirmedPrivateTransferError (tvb,tree,offset);
6087 offset = fVTCloseError (tvb,tree,offset);
6090 return fError (tvb, tree, offset);
6096 fErrorPDU(tvbuff_t *tvb, proto_tree *bacapp_tree, guint offset)
6097 { /* BACnet-Error-PDU */
6098 /* ASHRAE 135-2001 20.1.7 */
6100 proto_item *tc, *tt;
6101 proto_tree *bacapp_tree_control;
6104 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, TRUE);
6105 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
6107 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
6109 tmp = tvb_get_guint8(tvb, offset);
6110 tt = proto_tree_add_item(bacapp_tree, hf_bacapp_service, tvb,
6112 /* Error Handling follows... */
6113 return fBACnetError (tvb, bacapp_tree, offset, tmp);
6117 fRejectPDU(tvbuff_t *tvb, proto_tree *bacapp_tree, guint offset)
6118 { /* BACnet-Reject-PDU */
6119 /* ASHRAE 135-2001 20.1.8 */
6122 proto_tree *bacapp_tree_control;
6124 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset++, 1, TRUE);
6125 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
6127 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
6129 proto_tree_add_item(bacapp_tree, hf_BACnetRejectReason, tvb,
6135 fAbortPDU(tvbuff_t *tvb, proto_tree *bacapp_tree, guint offset)
6136 { /* BACnet-Abort-PDU */
6137 /* ASHRAE 135-2001 20.1.9 */
6140 proto_tree *bacapp_tree_control;
6142 tc = proto_tree_add_item(bacapp_tree, hf_bacapp_type, tvb, offset, 1, TRUE);
6143 bacapp_tree_control = proto_item_add_subtree(tc, ett_bacapp);
6145 proto_tree_add_item(bacapp_tree, hf_bacapp_SRV, tvb, offset++, 1, TRUE);
6146 proto_tree_add_item(bacapp_tree, hf_bacapp_invoke_id, tvb,
6148 proto_tree_add_item(bacapp_tree, hf_BACnetAbortReason, tvb,
6154 dissect_bacapp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
6156 gint8 tmp, bacapp_type;
6159 guint8 bacapp_service, bacapp_reason;
6160 guint8 bacapp_invoke_id;
6162 proto_tree *bacapp_tree;
6164 if (check_col(pinfo->cinfo, COL_PROTOCOL))
6165 col_set_str(pinfo->cinfo, COL_PROTOCOL, "BACnet-APDU");
6166 if (check_col(pinfo->cinfo, COL_INFO))
6167 col_set_str(pinfo->cinfo, COL_INFO, "BACnet APDU ");
6169 tmp = (gint) tvb_get_guint8(tvb, 0);
6170 bacapp_type = (tmp >> 4) & 0x0f;
6172 /* show some descriptive text in the INFO column */
6173 if (check_col(pinfo->cinfo, COL_INFO))
6175 col_clear(pinfo->cinfo, COL_INFO);
6176 col_add_str(pinfo->cinfo, COL_INFO,
6177 val_to_str(bacapp_type, BACnetTypeName, "#### unknown APDU ##### "));
6178 switch (bacapp_type)
6180 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST:
6181 /* segmented messages have 2 additional bytes */
6182 if (tmp & BACAPP_SEGMENTED_REQUEST)
6184 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 4);
6185 bacapp_service = tvb_get_guint8(tvb, offset + 5);
6189 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 2);
6190 bacapp_service = tvb_get_guint8(tvb, offset + 3);
6192 col_append_fstr(pinfo->cinfo, COL_INFO, "[invoke:%d]: %s",
6194 val_to_str(bacapp_service,
6195 BACnetConfirmedServiceChoice,
6196 bacapp_unknown_service_str));
6198 case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST:
6199 bacapp_service = tvb_get_guint8(tvb, offset + 1);
6200 col_append_fstr(pinfo->cinfo, COL_INFO, ": %s",
6201 val_to_str(bacapp_service,
6202 BACnetUnconfirmedServiceChoice,
6203 bacapp_unknown_service_str));
6205 case BACAPP_TYPE_SIMPLE_ACK:
6206 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
6207 bacapp_service = tvb_get_guint8(tvb, offset + 2);
6208 col_append_fstr(pinfo->cinfo, COL_INFO, "[invoke:%d]: %s",
6210 val_to_str(bacapp_service,
6211 BACnetConfirmedServiceChoice,
6212 bacapp_unknown_service_str));
6214 case BACAPP_TYPE_COMPLEX_ACK:
6215 /* segmented messages have 2 additional bytes */
6216 if (tmp & BACAPP_SEGMENTED_REQUEST)
6218 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 3);
6219 bacapp_service = tvb_get_guint8(tvb, offset + 4);
6223 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
6224 bacapp_service = tvb_get_guint8(tvb, offset + 2);
6226 col_append_fstr(pinfo->cinfo, COL_INFO, "[invoke:%d]: %s",
6228 val_to_str(bacapp_service,
6229 BACnetConfirmedServiceChoice,
6230 bacapp_unknown_service_str));
6232 case BACAPP_TYPE_SEGMENT_ACK:
6233 /* nothing more to add */
6235 case BACAPP_TYPE_ERROR:
6236 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
6237 bacapp_service = tvb_get_guint8(tvb, offset + 2);
6238 col_append_fstr(pinfo->cinfo, COL_INFO, "[invoke:%d]: %s",
6240 val_to_str(bacapp_service,
6241 BACnetConfirmedServiceChoice,
6242 bacapp_unknown_service_str));
6244 case BACAPP_TYPE_REJECT:
6245 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
6246 bacapp_reason = tvb_get_guint8(tvb, offset + 2);
6247 col_append_fstr(pinfo->cinfo, COL_INFO, "[invoke:%d]: %s",
6249 val_to_split_str(bacapp_reason,
6252 ASHRAE_Reserved_Fmt,
6253 Vendor_Proprietary_Fmt));
6255 case BACAPP_TYPE_ABORT:
6256 bacapp_invoke_id = tvb_get_guint8(tvb, offset + 1);
6257 bacapp_reason = tvb_get_guint8(tvb, offset + 2);
6258 col_append_fstr(pinfo->cinfo, COL_INFO, "[invoke:%d]: %s",
6260 val_to_split_str(bacapp_reason,
6263 ASHRAE_Reserved_Fmt,
6264 Vendor_Proprietary_Fmt));
6268 /* nothing more to add */
6274 ti = proto_tree_add_item(tree, proto_bacapp, tvb, offset, -1, FALSE);
6275 bacapp_tree = proto_item_add_subtree(ti, ett_bacapp);
6277 /* ASHRAE 135-2001 20.1.1 */
6278 switch (bacapp_type) {
6279 case BACAPP_TYPE_CONFIRMED_SERVICE_REQUEST: /* BACnet-Confirmed-Service-Request */
6280 offset = fConfirmedRequestPDU(tvb, bacapp_tree, offset);
6282 case BACAPP_TYPE_UNCONFIRMED_SERVICE_REQUEST: /* BACnet-Unconfirmed-Request-PDU */
6283 offset = fUnconfirmedRequestPDU(tvb, bacapp_tree, offset);
6285 case BACAPP_TYPE_SIMPLE_ACK: /* BACnet-Simple-Ack-PDU */
6286 offset = fSimpleAckPDU(tvb, bacapp_tree, offset);
6288 case BACAPP_TYPE_COMPLEX_ACK: /* BACnet-Complex-Ack-PDU */
6289 offset = fComplexAckPDU(tvb, bacapp_tree, offset);
6291 case BACAPP_TYPE_SEGMENT_ACK: /* BACnet-SegmentAck-PDU */
6292 offset = fSegmentAckPDU(tvb, bacapp_tree, offset);
6294 case BACAPP_TYPE_ERROR: /* BACnet-Error-PDU */
6295 offset = fErrorPDU(tvb, bacapp_tree, offset);
6297 case BACAPP_TYPE_REJECT: /* BACnet-Reject-PDU */
6298 offset = fRejectPDU(tvb, bacapp_tree, offset);
6300 case BACAPP_TYPE_ABORT: /* BACnet-Abort-PDU */
6301 offset = fAbortPDU(tvb, bacapp_tree, offset);
6306 next_tvb = tvb_new_subset(tvb,offset,-1,tvb_length_remaining(tvb,offset));
6307 call_dissector(data_handle,next_tvb, pinfo, tree);
6311 proto_register_bacapp(void)
6313 static hf_register_info hf[] = {
6315 { "APDU Type", "bacapp.type",
6316 FT_UINT8, BASE_DEC, VALS(BACnetTypeName), 0xf0, NULL, HFILL }
6318 { &hf_bacapp_pduflags,
6319 { "PDU Flags", "bacapp.pduflags",
6320 FT_UINT8, BASE_HEX, NULL, 0x0f, NULL, HFILL }
6323 { "Segmented Request", "bacapp.segmented_request",
6324 FT_BOOLEAN, 8, TFS(&segments_follow), 0x08, NULL, HFILL }
6327 { "More Segments", "bacapp.more_segments",
6328 FT_BOOLEAN, 8, TFS(&more_follow), 0x04, "More Segments Follow", HFILL }
6331 { "SA", "bacapp.SA",
6332 FT_BOOLEAN, 8, TFS(&segmented_accept), 0x02, "Segmented Response accepted", HFILL }
6334 { &hf_bacapp_max_adpu_size,
6335 { "Size of Maximum ADPU accepted", "bacapp.max_adpu_size",
6336 FT_UINT8, BASE_DEC, VALS(BACnetMaxAPDULengthAccepted), 0x0f, NULL, HFILL }
6338 { &hf_bacapp_response_segments,
6339 { "Max Response Segments accepted", "bacapp.response_segments",
6340 FT_UINT8, BASE_DEC, VALS(BACnetMaxSegmentsAccepted), 0x70, NULL, HFILL }
6342 { &hf_bacapp_objectType,
6343 { "Object Type", "bacapp.objectType",
6344 FT_UINT32, BASE_DEC, VALS(BACnetObjectType), 0xffc00000, NULL, HFILL }
6346 { &hf_bacapp_instanceNumber,
6347 { "Instance Number", "bacapp.instance_number",
6348 FT_UINT32, BASE_DEC, NULL, 0x003fffff, NULL, HFILL }
6350 { &hf_BACnetPropertyIdentifier,
6351 { "Property Identifier", "bacapp.property_identifier",
6352 FT_UINT32, BASE_DEC, VALS(BACnetPropertyIdentifier), 0, NULL, HFILL }
6354 { &hf_BACnetVendorIdentifier,
6355 { "Vendor Identifier", "bacapp.vendor_identifier",
6356 FT_UINT16, BASE_DEC, VALS(BACnetVendorIdentifiers), 0, NULL, HFILL }
6358 { &hf_bacapp_invoke_id,
6359 { "Invoke ID", "bacapp.invoke_id",
6360 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
6362 { &hf_bacapp_sequence_number,
6363 { "Sequence Number", "bacapp.sequence_number",
6364 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
6366 { &hf_bacapp_window_size,
6367 { "Proposed Window Size", "bacapp.window_size",
6368 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
6370 { &hf_bacapp_service,
6371 { "Service Choice", "bacapp.confirmed_service",
6372 FT_UINT8, BASE_DEC, VALS(BACnetConfirmedServiceChoice), 0x00, NULL, HFILL }
6374 { &hf_bacapp_uservice,
6375 { "Unconfirmed Service Choice", "bacapp.unconfirmed_service",
6376 FT_UINT8, BASE_DEC, VALS(BACnetUnconfirmedServiceChoice), 0x00, NULL, HFILL }
6379 { "NAK", "bacapp.NAK",
6380 FT_BOOLEAN, 8, NULL, 0x02, "negative ACK", HFILL }
6383 { "SRV", "bacapp.SRV",
6384 FT_BOOLEAN, 8, NULL, 0x01, "Server", HFILL }
6386 { &hf_BACnetRejectReason,
6387 { "Reject Reason", "bacapp.reject_reason",
6388 FT_UINT8, BASE_DEC, VALS(BACnetRejectReason), 0x00, NULL, HFILL }
6390 { &hf_BACnetAbortReason,
6391 { "Abort Reason", "bacapp.abort_reason",
6392 FT_UINT8, BASE_DEC, VALS(BACnetAbortReason), 0x00, NULL, HFILL }
6395 { "BACnet APDU variable part:", "bacapp.variable_part",
6396 FT_NONE, BASE_NONE, NULL, 0, "BACnet APDU variable part", HFILL }
6401 FT_BYTES, BASE_NONE, NULL, 0,
6404 { &hf_BACnetApplicationTagNumber,
6405 { "Application Tag Number",
6406 "bacapp.application_tag_number",
6407 FT_UINT8, BASE_DEC, VALS(&BACnetApplicationTagNumber), 0xF0,
6410 { &hf_BACnetContextTagNumber,
6411 { "Context Tag Number",
6412 "bacapp.context_tag_number",
6413 FT_UINT8, BASE_DEC, NULL, 0xF0,
6416 { &hf_BACnetExtendedTagNumber,
6417 { "Extended Tag Number",
6418 "bacapp.extended_tag_number",
6419 FT_UINT8, BASE_DEC, NULL, 0,
6422 { &hf_BACnetNamedTag,
6425 FT_UINT8, BASE_DEC, VALS(&BACnetTagNames), 0x07,
6428 { &hf_BACnetCharacterSet,
6429 { "String Character Set",
6430 "bacapp.string_character_set",
6431 FT_UINT8, BASE_DEC, VALS(&BACnetCharacterSet),0,
6434 { &hf_BACnetTagClass,
6435 { "Tag Class", "bacapp.tag_class",
6436 FT_BOOLEAN, 8, TFS(&BACnetTagClass), 0x08, NULL, HFILL }
6438 { &hf_bacapp_tag_lvt,
6439 { "Length Value Type",
6441 FT_UINT8, BASE_DEC, NULL, 0,
6444 { &hf_bacapp_tag_value8,
6446 "bacapp.tag_value8",
6447 FT_UINT8, BASE_DEC, NULL, 0,
6450 { &hf_bacapp_tag_value16,
6451 { "Tag Value 16-bit",
6452 "bacapp.tag_value16",
6453 FT_UINT16, BASE_DEC, NULL, 0,
6456 { &hf_bacapp_tag_value32,
6457 { "Tag Value 32-bit",
6458 "bacapp.tag_value32",
6459 FT_UINT32, BASE_DEC, NULL, 0,
6462 { &hf_bacapp_tag_ProcessId,
6463 { "ProcessIdentifier", "bacapp.processId",
6464 FT_UINT32, BASE_DEC, NULL, 0, "Process Identifier", HFILL }
6466 { &hf_bacapp_tag_initiatingObjectType,
6467 { "ObjectType", "bacapp.objectType",
6468 FT_UINT16, BASE_DEC, VALS(BACnetObjectType), 0x00, "Object Type", HFILL }
6471 static gint *ett[] = {
6473 &ett_bacapp_control,
6478 proto_bacapp = proto_register_protocol("Building Automation and Control Network APDU",
6479 "BACapp", "bacapp");
6481 proto_register_field_array(proto_bacapp, hf, array_length(hf));
6482 proto_register_subtree_array(ett, array_length(ett));
6483 register_dissector("bacapp", dissect_bacapp, proto_bacapp);
6488 proto_reg_handoff_bacapp(void)
6490 data_handle = find_dissector("data");
6494 fConvertXXXtoUTF8 (gchar *in, size_t *inbytesleft, gchar *out, size_t *outbytesleft, const gchar *fromcoding)
6499 if ((icd = g_iconv_open ("UTF-8", fromcoding)) != (GIConv) -1) {
6500 i = (guint32) g_iconv (icd, &in, inbytesleft, &out, outbytesleft);
6501 /* g_iconv incremented 'out'; now ensure it's NULL terminated */
6504 g_iconv_close (icd);
6508 memcpy (out, in, *inbytesleft);
6509 out[*inbytesleft] = '\0';
6510 *outbytesleft -= *inbytesleft;