From Anders Broman:
[obnox/wireshark/wip.git] / packet-h450.c
1 /* packet-h450.c
2  * Routines for H.450 packet dissection
3  * 2003  Graeme Reid (graeme.reid@norwoodsystems.com)
4  *
5  * Copied from packet-h225.c and packet-h245.c
6  *
7  * $Id: packet-h450.c,v 1.3 2003/10/02 22:44:19 guy Exp $
8  *
9  * Ethereal - Network traffic analyzer
10  * By Gerald Combs <gerald@ethereal.com>
11  * Copyright 1998 Gerald Combs
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26  */
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <glib.h>
33 #include <epan/packet.h>
34 #include <epan/conversation.h>
35
36 #include <stdio.h>
37 #include <string.h>
38
39 #include "prefs.h"
40 #include "packet-per.h"
41 #include "packet-h225.h"
42 #include "packet-h245.h"
43
44 /* H.450.2 Call Transfer constants */
45 #define CallTransferIdentify        7
46 #define CallTransferAbandon         8
47 #define CallTransferInitiate        9
48 #define CallTransferSetup           10
49 #define CallTransferUpdate          13
50 #define SubaddressTransfer          14
51 #define CallTransferComplete        12
52 #define CallTransferActive          11
53
54 /* H.450.3 Call Diversion constants */
55 #define ActivateDiversionQ          15
56 #define DeactivateDiversionQ        16
57 #define InterrogateDiversionQ       17
58 #define CheckRestriction            18
59 #define CallRerouting               19
60 #define DivertingLegInformation1    20
61 #define DivertingLegInformation2    21
62 #define DivertingLegInformation3    22
63 #define DivertingLegInformation4    100
64 #define CfnrDivertedLegFailed       23
65
66 /* H.450.4 Call Hold constants */
67 #define HoldNotific                 101
68 #define RetrieveNotific             102
69 #define RemoteHold                  103
70 #define RemoteRetrieve              104
71
72 /* H.450.5 Call Park and Pickup constants */
73 #define CpRequest                   106
74 #define CpSetup                     107
75 #define GroupIndicationOn           108
76 #define GroupIndicationOff          109
77 #define Pickrequ                    110
78 #define Pickup                      111
79 #define PickExe                     112
80 #define CpNotify                    113
81 #define CpickupNotify               114
82
83 /* H.450.6 Call Waiting constants */
84 #define CallWaiting                 105
85
86 /* TODO - define other H.450.x constants here */
87
88 static dissector_handle_t h4501_handle;
89
90 static int proto_h4501 = -1;
91
92 static int hf_h4501 = -1;
93 static int hf_h4501_EntityType = -1;
94 static int hf_h4501_NetworkFacilityExtension = -1;
95 static int hf_h4501_InterpretationApdu = -1;
96 static int hf_h4501_constrained_invokeId = -1;
97 static int hf_h4501_invokeId = -1;
98 static int hf_h4501_localOpcode = -1;
99 static int hf_h4501_globalCode = -1;
100 static int hf_h4501_opcode = -1;
101 static int hf_h4501_destinationAddress = -1;
102 static int hf_h4501_EndpointAddress = -1;
103 static int hf_h4501_H225InformationElement = -1;
104 static int hf_h4501_SubaddressInformation = -1;
105 static int hf_h4501_oddCountIndicator = -1;
106 static int hf_h4501_UserSpecifiedSubaddress = -1;
107 static int hf_h4501_NSAPAddress = -1;
108 static int hf_h4501_PartySubaddress = -1;
109 static int hf_h4501_argumentExtension = -1;
110 static int hf_h4501_argument = -1;
111 static int hf_h4501_Invoke = -1;
112 static int hf_h4501_resultExtension = -1;
113 static int hf_h4501_ReturnResult_result = -1;
114 static int hf_h4501_result = -1;
115 static int hf_h4501_ReturnResult = -1;
116 static int hf_h4501_localErrorCode = -1;
117 static int hf_h4501_errorCode = -1;
118 static int hf_h4501_parameter = -1;
119 static int hf_h4501_ReturnError = -1;
120 static int hf_h4501_GeneralProblem = -1;
121 static int hf_h4501_InvokeProblem = -1;
122 static int hf_h4501_ReturnResultProblem = -1;
123 static int hf_h4501_ReturnErrorProblem = -1;
124 static int hf_h4501_problem = -1;
125 static int hf_h4501_Reject = -1;
126 static int hf_h4501_ROS = -1;
127 static int hf_h4501_rosApdus = -1;
128 static int hf_h4501_ServiceApdus = -1;
129
130 static int hf_h4502_nonStandardData = -1;
131 static int hf_h4502_DummyArg = -1;
132 static int hf_h4502_CallIdentity = -1;
133 static int hf_h4502_CTInitiateArg = -1;
134 static int hf_h4502_CTSetupArg = -1;
135 static int hf_h4502_redirectionInfo = -1;
136 static int hf_h4502_CTUpdateArg = -1;
137 static int hf_h4502_SubaddressTransferArg = -1;
138 static int hf_h4502_EndDesignation = -1;
139 static int hf_h4502_CallStatus = -1;
140 static int hf_h4502_CTCompleteArg = -1;
141 static int hf_h4502_connectedInfo = -1;
142 static int hf_h4502_CTActiveArg = -1;
143 static int hf_h4502_CTIdentifyRes = -1;
144 static int hf_h4502_DummyRes = -1;
145
146 static gint ett_h4501 = -1;
147 static gint ett_h4501_EntityType = -1;
148 static gint ett_h4501_NetworkFacilityExtension = -1;
149 static gint ett_h4501_InterpretationApdu = -1;
150 static gint ett_h4501_opcode = -1;
151 static gint ett_h4501_destinationAddress = -1;
152 static gint ett_h4501_EndpointAddress = -1;
153 static gint ett_h4501_UserSpecifiedSubaddress = -1;
154 static gint ett_h4501_PartySubaddress = -1;
155 static gint ett_h4501_argumentExtension = -1;
156 static gint ett_h4501_Invoke = -1;
157 static gint ett_h4501_resultExtension = -1;
158 static gint ett_h4501_result = -1;
159 static gint ett_h4501_ReturnResult = -1;
160 static gint ett_h4501_errorCode = -1;
161 static gint ett_h4501_ReturnError = -1;
162 static gint ett_h4501_problem = -1;
163 static gint ett_h4501_Reject = -1;
164 static gint ett_h4501_ROS = -1;
165 static gint ett_h4501_rosApdus = -1;
166 static gint ett_h4501_ServiceApdus = -1;
167
168 static gint ett_h4502_DummyArg = -1;
169 static gint ett_h4502_CTInitiateArg = -1;
170 static gint ett_h4502_CTSetupArg = -1;
171 static gint ett_h4502_CTUpdateArg = -1;
172 static gint ett_h4502_SubaddressTransferArg = -1;
173 static gint ett_h4502_CTCompleteArg = -1;
174 static gint ett_h4502_CTActiveArg = -1;
175 static gint ett_h4502_CTIdentifyRes = -1;
176 static gint ett_h4502_DummyRes = -1;
177
178 static guint32 localOpcode;
179 static guint32 localErrorCode;
180
181 static int
182 dissect_h4501_NULL(tvbuff_t *tvb _U_, int offset, packet_info *pinfo _U_, proto_tree *tree _U_)
183 {
184         return offset;
185 }
186
187
188 static const value_string EntityType_vals[] = {
189         { 0, "endpoint" },
190         { 1, "anyEntity" },
191         { 0, NULL}
192 };
193 static per_choice_t EntityType_choice[] = {
194         { 0, "endpoint", EXTENSION_ROOT, 
195                 dissect_h4501_NULL },
196         { 1, "anyEntity", EXTENSION_ROOT, 
197                 dissect_h4501_NULL },
198         { 0, NULL, 0, NULL }
199 };
200 static int
201 dissect_h4501_EntityType(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
202 {
203    offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h4501_EntityType, ett_h4501_EntityType, EntityType_choice, "EntityType", NULL);
204    return offset;
205 }
206
207
208 static per_sequence_t NetworkFacilityExtension_sequence[] = {
209         { "sourceEntity", EXTENSION_ROOT, NOT_OPTIONAL,
210                 dissect_h4501_EntityType },
211         { "sourceEntityAddress", EXTENSION_ROOT, OPTIONAL,
212                 dissect_h225_AliasAddress },
213         { "destinationEntity", EXTENSION_ROOT, NOT_OPTIONAL,
214                 dissect_h4501_EntityType },
215         { "destinationEntityAddress", EXTENSION_ROOT, OPTIONAL,
216                 dissect_h225_AliasAddress },
217         { NULL, 0, 0, NULL }
218 };
219 static int
220 dissect_h4501_NetworkFacilityExtension(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
221 {
222    offset=dissect_per_sequence(tvb, offset, pinfo, tree, hf_h4501_NetworkFacilityExtension, ett_h4501_NetworkFacilityExtension, NetworkFacilityExtension_sequence);
223    return offset;
224 }
225
226
227 static const value_string InterpretationApdu_vals[] = {
228         { 0, "discardAnyUnrecognizedInvokePdu" },
229         { 1, "clearCallIfAnyInvokePduNotRecognized" },
230         { 2, "rejectAnyUnrecognizedInvokePdu" },
231         { 0, NULL}
232 };
233 static per_choice_t InterpretationApdu_choice[] = {
234         { 0, "discardAnyUnrecognizedInvokePdu", EXTENSION_ROOT, 
235                 dissect_h4501_NULL },
236         { 1, "clearCallIfAnyInvokePduNotRecognized", EXTENSION_ROOT, 
237                 dissect_h4501_NULL },
238         { 2, "rejectAnyUnrecognizedInvokePdu", EXTENSION_ROOT, 
239                 dissect_h4501_NULL },
240         { 0, NULL, 0, NULL }
241 };
242 static int
243 dissect_h4501_InterpretationApdu(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
244 {
245    offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h4501_InterpretationApdu, ett_h4501_InterpretationApdu, InterpretationApdu_choice, "InterpretationApdu", NULL);
246    return offset;
247 }
248
249
250 static int
251 dissect_h4501_constrained_invokeId(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
252 {
253    offset=dissect_per_constrained_integer(tvb, offset, pinfo, tree, hf_h4501_constrained_invokeId, 0, 65535, NULL, NULL, FALSE);
254         return offset;
255 }
256
257
258 static int
259 dissect_h4501_invokeId(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
260 {
261    offset=dissect_per_integer(tvb, offset, pinfo, tree, hf_h4501_invokeId, NULL, NULL);
262         return offset;
263 }
264
265
266 static const value_string localOpcode_vals[] = {
267    /* H.450.2 Call Transfer opcodes */
268    { CallTransferIdentify,    "callTransferIdentify"},
269    { CallTransferAbandon,     "callTransferAbandon"},
270    { CallTransferInitiate,    "callTransferInitiate"},
271    { CallTransferSetup,       "callTransferSetup"},
272    { CallTransferUpdate,      "callTransferUpdate"},
273    { SubaddressTransfer,      "subaddressTransfer"},
274    { CallTransferComplete,    "callTransferComplete"},
275    { CallTransferActive,      "callTransferActive"},
276
277    /* H.450.3 Call Diversion opcodes */
278    { ActivateDiversionQ,      "activateDiversionQ"},
279    { DeactivateDiversionQ,    "deactivateDiversionQ"},
280    { InterrogateDiversionQ,   "interrogateDiversionQ"},
281    { CheckRestriction,        "checkRestriction"},
282    { CallRerouting,           "callRerouting"},
283    { DivertingLegInformation1,"divertingLegInformation1"},
284    { DivertingLegInformation2,"divertingLegInformation2"},
285    { DivertingLegInformation3,"divertingLegInformation3"},
286    { DivertingLegInformation4,"divertingLegInformation4"},
287    { CfnrDivertedLegFailed,   "cfnrDivertedLegFailed"},
288
289    /* H.450.4 Call Hold opcodes */
290    { HoldNotific,             "holdNotific"},
291    { RetrieveNotific,         "retrieveNotific"},
292    { RemoteHold,              "remoteHold"},
293    { RemoteRetrieve,          "remoteRetrieve"},
294
295    /* H.450.5 Call Park and Pickup opcodes */
296    { CpRequest,               "cpRequest"},
297    { CpSetup,                 "cpSetup"},
298    { GroupIndicationOn,       "groupIndicationOn"},
299    { GroupIndicationOff,      "groupIndicationOff"},
300    { Pickrequ,                "pickrequ"},
301    { Pickup,                  "pickup"},
302    { PickExe,                 "pickExe"},
303    { CpNotify,                "cpNotify"},
304    { CpickupNotify,           "cpickupNotify"},
305
306    /* H.450.6 Call Waiting opcodes */
307    { CallWaiting,             "callWaiting"},
308
309    /* TODO - add other H.450.x invoke opcodes here */
310
311         {  0, NULL }
312 };
313 static int
314 dissect_h4501_localOpcode(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
315 {
316    offset=dissect_per_integer(tvb, offset, pinfo, tree, hf_h4501_localOpcode, &localOpcode, NULL);
317         return offset;
318 }
319
320
321 static int
322 dissect_h4501_globalCode(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
323 {
324         offset=dissect_per_object_identifier(tvb, offset, pinfo, tree, hf_h4501_globalCode, NULL);
325    return offset;
326 }
327
328
329 static const value_string opcode_vals[] = {
330         { 0, "local" },
331         { 1, "global" },
332         { 0, NULL}
333 };
334 static per_choice_t opcode_choice[] = {
335         { 0, "local", NO_EXTENSIONS,
336                 dissect_h4501_localOpcode },
337         { 1, "global", NO_EXTENSIONS,
338                 dissect_h4501_globalCode },
339         { 0, NULL, 0, NULL }
340 };
341 static int
342 dissect_h4501_opcode(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
343 {
344    offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h4501_opcode, ett_h4501_opcode, opcode_choice, "Opcode", NULL);
345    return offset;
346 }
347
348
349 static int
350 dissect_h4501_ExtensionSeq(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
351 {
352 NOT_DECODED_YET("H.450.1 ExtensionSeq");
353    return offset;
354 }
355
356
357 static int
358 dissect_h4502_nonStandardData(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
359 {
360         offset = dissect_h225_NonStandardParameter(tvb, offset, pinfo, tree, 
361                                 hf_h4502_nonStandardData);
362         return offset;
363 }
364
365 static const value_string Extension_vals[] = {
366         { 0, "extensionSeq" },
367         { 1, "nonStandardData" },
368         { 0, NULL}
369 };
370 static per_choice_t Extension_choice[] = {
371         { 0, "extensionSeq", NO_EXTENSIONS, 
372                 dissect_h4501_ExtensionSeq },
373         { 1, "nonStandardData", NO_EXTENSIONS, 
374                 dissect_h4502_nonStandardData },
375         { 0, NULL, 0, NULL }
376 };
377 static int
378 dissect_h4502_DummyArg(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
379 {
380    offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h4502_DummyArg, ett_h4502_DummyArg, Extension_choice, "DummyArg", NULL);
381    return offset;
382 }
383
384
385 static int
386 dissect_h4502_CallIdentity(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
387 {
388    offset=dissect_per_NumericString(tvb, offset, pinfo, tree, hf_h4502_CallIdentity, 0, 4);
389    return offset;
390 }
391
392
393 static int
394 dissect_h4501_destinationAddress(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
395 {
396         offset=dissect_per_sequence_of(tvb, offset, pinfo, tree, hf_h4501_destinationAddress, ett_h4501_destinationAddress, dissect_h225_AliasAddress);
397    return offset;
398 }
399
400
401 static per_sequence_t EndpointAddress_sequence[] = {
402         { "destinationAddress", EXTENSION_ROOT, NOT_OPTIONAL,
403                 dissect_h4501_destinationAddress },
404         { "remoteExtensionAddress", EXTENSION_ROOT, OPTIONAL,
405                 dissect_h225_AliasAddress },
406         { NULL, 0, 0, NULL }
407 };
408 static int
409 dissect_h4501_EndpointAddress(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
410 {
411    offset=dissect_per_sequence(tvb, offset, pinfo, tree, hf_h4501_EndpointAddress, ett_h4501_EndpointAddress, EndpointAddress_sequence);
412    return offset;
413 }
414
415
416 static int
417 dissect_h4501_argumentExtension(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
418 {
419    offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h4501_argumentExtension, ett_h4501_argumentExtension, Extension_choice, "argumentExtension", NULL);
420    return offset;
421 }
422
423
424 static per_sequence_t CTInitiateArg_sequence[] = {
425         { "callIdentity", EXTENSION_ROOT, NOT_OPTIONAL,
426                 dissect_h4502_CallIdentity },
427         { "reroutingNumber", EXTENSION_ROOT, NOT_OPTIONAL,
428                 dissect_h4501_EndpointAddress },
429         { "argumentExtension", EXTENSION_ROOT, OPTIONAL,
430                 dissect_h4501_argumentExtension },
431         { NULL, 0, 0, NULL }
432 };
433 static int
434 dissect_h4502_CTInitiateArg(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
435 {
436    offset=dissect_per_sequence(tvb, offset, pinfo, tree, hf_h4502_CTInitiateArg, ett_h4502_CTInitiateArg, CTInitiateArg_sequence);
437    return offset;
438 }
439
440
441 static per_sequence_t CTSetupArg_sequence[] = {
442         { "callIdentity", EXTENSION_ROOT, NOT_OPTIONAL,
443                 dissect_h4502_CallIdentity },
444         { "transferringNumber", EXTENSION_ROOT, OPTIONAL,
445                 dissect_h4501_EndpointAddress },
446         { "argumentExtension", EXTENSION_ROOT, OPTIONAL,
447                 dissect_h4501_argumentExtension },
448         { NULL, 0, 0, NULL }
449 };
450 static int
451 dissect_h4502_CTSetupArg(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
452 {
453    offset=dissect_per_sequence(tvb, offset, pinfo, tree, hf_h4502_CTSetupArg, ett_h4502_CTSetupArg, CTSetupArg_sequence);
454    return offset;
455 }
456
457
458 static int
459 dissect_h4502_redirectionInfo(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
460 {
461         offset=dissect_per_BMPString(tvb, offset, pinfo, tree, hf_h4502_redirectionInfo, 1, 128);
462    return offset;
463 }
464
465
466 static int
467 dissect_h4501_H225InformationElement(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
468 {
469    offset=dissect_per_octet_string(tvb, offset, pinfo, tree, hf_h4501_H225InformationElement, -1, -1, NULL, NULL);
470    return offset;
471 }
472
473
474 static per_sequence_t CTUpdateArg_sequence[] = {
475         { "redirectionNumber", EXTENSION_ROOT, NOT_OPTIONAL,
476                 dissect_h4501_EndpointAddress },
477         { "redirectionInfo", EXTENSION_ROOT, OPTIONAL,
478                 dissect_h4502_redirectionInfo },
479         { "basicCallInfoElements", EXTENSION_ROOT, OPTIONAL,
480                 dissect_h4501_H225InformationElement },
481         { "argumentExtension", EXTENSION_ROOT, OPTIONAL,
482                 dissect_h4501_argumentExtension },
483         { NULL, 0, 0, NULL }
484 };
485 static int
486 dissect_h4502_CTUpdateArg(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
487 {
488    offset=dissect_per_sequence(tvb, offset, pinfo, tree, hf_h4502_CTUpdateArg, ett_h4502_CTUpdateArg, CTUpdateArg_sequence);
489    return offset;
490 }
491
492
493 static int
494 dissect_h4501_SubaddressInformation(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
495 {
496         offset=dissect_per_octet_string(tvb, offset, pinfo, tree, hf_h4501_SubaddressInformation, 1, 20, NULL, NULL);
497    return offset;
498 }
499
500
501 static const true_false_string tfs_oddCountIndicator_bit = {
502         "oddCountIndicator bit is SET",
503         "oddCountIndicator bit is CLEAR"
504 };
505 static int
506 dissect_h4501_oddCountIndicator(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
507 {
508         offset=dissect_per_boolean(tvb, offset, pinfo, tree, hf_h4501_oddCountIndicator, NULL, NULL);
509    return offset;
510 }
511
512
513 static per_sequence_t UserSpecifiedSubaddress_sequence[] = {
514         { "subaddressInformation", EXTENSION_ROOT, NOT_OPTIONAL,
515                 dissect_h4501_SubaddressInformation },
516         { "oddCountIndicator", EXTENSION_ROOT, OPTIONAL,
517                 dissect_h4501_oddCountIndicator },
518         { NULL, 0, 0, NULL }
519 };
520 static int
521 dissect_h4501_UserSpecifiedSubaddress(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
522 {
523    offset=dissect_per_sequence(tvb, offset, pinfo, tree, hf_h4501_UserSpecifiedSubaddress, ett_h4501_UserSpecifiedSubaddress, UserSpecifiedSubaddress_sequence);
524    return offset;
525 }
526
527
528 static int
529 dissect_h4501_NSAPSubaddress(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
530 {
531         offset=dissect_per_octet_string(tvb, offset, pinfo, tree, hf_h4501_NSAPAddress, 1, 20, NULL, NULL);
532    return offset;
533 }
534
535
536 static const value_string PartySubaddress_vals[] = {
537         { 0, "userSpecifiedSubaddress" },
538         { 1, "nsapSubaddress" },
539         { 0, NULL}
540 };
541 static per_choice_t PartySubaddress_choice[] = {
542         { 0, "userSpecifiedSubaddress", EXTENSION_ROOT, 
543                 dissect_h4501_UserSpecifiedSubaddress },
544         { 1, "nsapSubaddress", EXTENSION_ROOT, 
545                 dissect_h4501_NSAPSubaddress },
546         { 0, NULL, 0, NULL }
547 };
548 static int
549 dissect_h4501_PartySubaddress(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
550 {
551    offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h4501_PartySubaddress, ett_h4501_PartySubaddress, PartySubaddress_choice, "PartySubaddress", NULL);
552    return offset;
553 }
554
555
556 static per_sequence_t SubaddressTransferArg_sequence[] = {
557         { "redirectionSubaddress", EXTENSION_ROOT, NOT_OPTIONAL,
558                 dissect_h4501_PartySubaddress },
559         { "argumentExtension", EXTENSION_ROOT, OPTIONAL,
560                 dissect_h4501_argumentExtension },
561         { NULL, 0, 0, NULL }
562 };
563 static int
564 dissect_h4502_SubaddressTransferArg(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
565 {
566    offset=dissect_per_sequence(tvb, offset, pinfo, tree, hf_h4502_SubaddressTransferArg, ett_h4502_SubaddressTransferArg, SubaddressTransferArg_sequence);
567    return offset;
568 }
569
570
571 static const value_string EndDesignation_vals[] = {
572    {  0, "primaryEnd"},
573    {  1, "secondaryEnd"},
574    {  0, NULL }
575 };
576 static int
577 dissect_h4502_EndDesignation(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
578 {
579    offset=dissect_per_constrained_integer(tvb, offset, pinfo, tree, hf_h4502_EndDesignation, 0, 1, NULL, NULL, TRUE);
580    return offset;
581 }
582
583
584 static const value_string CallStatus_vals[] = {
585    {  0, "answered"},
586    {  1, "alerting"},
587    {  0, NULL }
588 };
589 static int
590 dissect_h4502_CallStatus(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
591 {
592    offset=dissect_per_constrained_integer(tvb, offset, pinfo, tree, hf_h4502_CallStatus, 0, 1, NULL, NULL, TRUE);
593    return offset;
594 }
595
596
597 static per_sequence_t CTCompleteArg_sequence[] = {
598         { "endDesignation", EXTENSION_ROOT, NOT_OPTIONAL,
599                 dissect_h4502_EndDesignation },
600         { "redirectionNumber", EXTENSION_ROOT, NOT_OPTIONAL,
601                 dissect_h4501_EndpointAddress },
602         { "basicCallInfoElements", EXTENSION_ROOT, OPTIONAL,
603                 dissect_h4501_H225InformationElement },
604         { "redirectionInfo", EXTENSION_ROOT, OPTIONAL,
605                 dissect_h4502_redirectionInfo },
606         { "callStatus", EXTENSION_ROOT, NOT_OPTIONAL,
607                 dissect_h4502_CallStatus },
608         { "argumentExtension", EXTENSION_ROOT, OPTIONAL,
609                 dissect_h4501_argumentExtension },
610         { NULL, 0, 0, NULL }
611 };
612 static int
613 dissect_h4502_CTCompleteArg(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
614 {
615    offset=dissect_per_sequence(tvb, offset, pinfo, tree, hf_h4502_CTCompleteArg, ett_h4502_CTCompleteArg, CTCompleteArg_sequence);
616    return offset;
617 }
618
619
620 static int
621 dissect_h4502_connectedInfo(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
622 {
623         offset=dissect_per_BMPString(tvb, offset, pinfo, tree, hf_h4502_connectedInfo, 1, 128);
624    return offset;
625 }
626
627
628 static per_sequence_t CTActiveArg_sequence[] = {
629         { "connectedAddress", EXTENSION_ROOT, NOT_OPTIONAL,
630                 dissect_h4501_EndpointAddress },
631         { "basicCallInfoElements", EXTENSION_ROOT, OPTIONAL,
632                 dissect_h4501_H225InformationElement },
633         { "connectedInfo", EXTENSION_ROOT, OPTIONAL,
634                 dissect_h4502_connectedInfo },
635         { "argumentExtension", EXTENSION_ROOT, OPTIONAL,
636                 dissect_h4501_argumentExtension },
637         { NULL, 0, 0, NULL }
638 };
639 static int
640 dissect_h4502_CTActiveArg(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
641 {
642    offset=dissect_per_sequence(tvb, offset, pinfo, tree, hf_h4502_CTActiveArg, ett_h4502_CTActiveArg, CTActiveArg_sequence);
643    return offset;
644 }
645
646
647 static int
648 dissect_h4501_argument(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
649 {
650    tvbuff_t *argument_tvb;
651    guint32 argument_offset=0;
652    guint32 argument_len=0;
653
654    offset=dissect_per_octet_string(tvb, offset, pinfo, tree, -1, -1, -1, &argument_offset, &argument_len);
655
656    if(argument_len){
657       argument_tvb = tvb_new_subset(tvb, argument_offset, argument_len, argument_len);
658
659       switch (localOpcode) {
660       case CallTransferIdentify:
661       case CallTransferAbandon:
662          offset = dissect_h4502_DummyArg(argument_tvb, 0, pinfo, tree);
663          break;
664
665       case CallTransferInitiate:
666          offset = dissect_h4502_CTInitiateArg(argument_tvb, 0, pinfo, tree);
667          break;
668
669       case CallTransferSetup:
670          offset = dissect_h4502_CTSetupArg(argument_tvb, 0, pinfo, tree);
671          break;
672
673       case CallTransferUpdate:
674          offset = dissect_h4502_CTUpdateArg(argument_tvb, 0, pinfo, tree);
675          break;
676
677       case SubaddressTransfer:
678          offset = dissect_h4502_SubaddressTransferArg(argument_tvb, 0, pinfo, tree);
679          break;
680
681       case CallTransferComplete:
682          offset = dissect_h4502_CTCompleteArg(argument_tvb, 0, pinfo, tree);
683          break;
684
685       case CallTransferActive:
686          offset = dissect_h4502_CTActiveArg(argument_tvb, 0, pinfo, tree);
687          break;
688
689       /* TODO - decode other H.450.x invoke arguments here */
690
691       default:
692 NOT_DECODED_YET("Unrecognized H.450.x operation");
693          break;
694       }
695    }
696         return offset;
697 }
698
699
700 static per_sequence_t Invoke_sequence[] = {
701         { "invokeID", NO_EXTENSIONS, NOT_OPTIONAL,
702                 dissect_h4501_constrained_invokeId },
703         { "linkedId", NO_EXTENSIONS, OPTIONAL,
704                 dissect_h4501_invokeId },
705         { "opcode", NO_EXTENSIONS, NOT_OPTIONAL,
706                 dissect_h4501_opcode },
707         { "argument", NO_EXTENSIONS, OPTIONAL,
708                 dissect_h4501_argument },
709         { NULL, 0, 0, NULL }
710 };
711 static int
712 dissect_h4501_Invoke(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
713 {
714    offset=dissect_per_sequence(tvb, offset, pinfo, tree, hf_h4501_Invoke, ett_h4501_Invoke, Invoke_sequence);
715    return offset;
716 }
717
718
719 static int
720 dissect_h4501_resultExtension(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
721 {
722    offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h4501_resultExtension, ett_h4501_resultExtension, Extension_choice, "resultExtension", NULL);
723    return offset;
724 }
725
726
727 static per_sequence_t CTIdentifyRes_sequence[] = {
728         { "callIdentity", EXTENSION_ROOT, NOT_OPTIONAL,
729                 dissect_h4502_CallIdentity },
730         { "reroutingNumber", EXTENSION_ROOT, NOT_OPTIONAL,
731                 dissect_h4501_EndpointAddress },
732         { "resultExtension", EXTENSION_ROOT, OPTIONAL,
733                 dissect_h4501_resultExtension },
734         { NULL, 0, 0, NULL }
735 };
736 static int
737 dissect_h4502_CTIdentifyRes(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
738 {
739    offset=dissect_per_sequence(tvb, offset, pinfo, tree, hf_h4502_CTIdentifyRes, ett_h4502_CTIdentifyRes, CTIdentifyRes_sequence);
740    return offset;
741 }
742
743
744 static int
745 dissect_h4502_DummyRes(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
746 {
747    offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h4502_DummyRes, ett_h4502_DummyRes, Extension_choice, "DummyRes", NULL);
748    return offset;
749 }
750
751
752 static int
753 dissect_h4501_ReturnResult_result(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
754 {
755    tvbuff_t *result_tvb;
756    guint32 result_offset=0;
757    guint32 result_len=0;
758
759    offset=dissect_per_octet_string(tvb, offset, pinfo, tree, -1, -1, -1, &result_offset, &result_len);
760
761    if(result_len){
762       result_tvb = tvb_new_subset(tvb, result_offset, result_len, result_len);
763
764       switch (localOpcode) {
765       case CallTransferIdentify:
766          offset = dissect_h4502_CTIdentifyRes(result_tvb, 0, pinfo, tree);
767          break;
768
769       case CallTransferInitiate:
770       case CallTransferSetup:
771          offset = dissect_h4502_DummyRes(result_tvb, 0, pinfo, tree);
772          break;
773
774       default:
775 NOT_DECODED_YET("Unrecognized H.450.x return result");
776          break;
777       }
778    }
779
780    return offset;
781 }
782
783
784 static per_sequence_t result_sequence[] = {
785         { "opcode", EXTENSION_ROOT, NOT_OPTIONAL,
786                 dissect_h4501_opcode },
787         { "result", EXTENSION_ROOT, NOT_OPTIONAL,
788                 dissect_h4501_ReturnResult_result },
789         { NULL, 0, 0, NULL }
790 };
791 static int
792 dissect_h4501_result(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
793 {
794    offset=dissect_per_sequence(tvb, offset, pinfo, tree, hf_h4501_result, ett_h4501_result, result_sequence);
795    return offset;
796 }
797
798
799 static per_sequence_t ReturnResult_sequence[] = {
800         { "invokeID", NO_EXTENSIONS, NOT_OPTIONAL,
801                 dissect_h4501_invokeId },
802         { "result", NO_EXTENSIONS, OPTIONAL,
803                 dissect_h4501_result },
804         { NULL, 0, 0, NULL }
805 };
806 static int
807 dissect_h4501_ReturnResult(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
808 {
809    offset=dissect_per_sequence(tvb, offset, pinfo, tree, hf_h4501_ReturnResult, ett_h4501_ReturnResult, ReturnResult_sequence);
810    return offset;
811 }
812
813
814 static const value_string localErrorCode_vals[] = {
815    /* H.450.1 general error list */
816    {    0, "userNotSubscribed"},
817    {    1, "RejectedByNetwork"},
818    {    2, "RejectedByUser"},
819    {    3, "NotAvailable"},
820    {    5, "InsufficientInformation"},
821    {    6, "InvalidServedUserNumber"},
822    {    7, "InvalidCallState"},
823    {    8, "BasicServiceNotProvided"},
824    {    9, "NotIncomingCall"},
825    {   10, "SupplementaryServiceInteractionNotAllowed"},
826    {   11, "ResourceUnavailable"},
827    {   25, "CallFailure"},
828    {   43, "ProceduralError"},
829
830    /* H.450.2 Call Transfer return errors */
831    { 1004, "invalidReroutingNumber"},
832    { 1005, "unrecognizedCallIdentity"},
833    { 1006, "establishmentFailure"},
834    { 1008, "unspecified"},
835
836    /* H.450.4 Call Hold return errors */
837    { 2002, "undefined"},
838
839    /* H.450.5 Call Park and Pickup return errors */
840    { 2000, "callPickupIdInvalid"},
841    { 2001, "callAlreadyPickedUp"},
842
843    /* TODO - add other H.450.x error codes here */
844
845    {  0, NULL }
846 };
847 static int
848 dissect_h4501_localErrorCode(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
849 {
850    offset=dissect_per_integer(tvb, offset, pinfo, tree, hf_h4501_localErrorCode, &localErrorCode, NULL);
851         return offset;
852 }
853
854
855 static const value_string errorCode_vals[] = {
856         { 0, "local" },
857         { 1, "global" },
858         { 0, NULL}
859 };
860 static per_choice_t errorCode_choice[] = {
861         { 0, "local", NO_EXTENSIONS,
862                 dissect_h4501_localErrorCode },
863         { 1, "global", NO_EXTENSIONS,
864                 dissect_h4501_globalCode },
865         { 0, NULL, 0, NULL }
866 };
867 static int
868 dissect_h4501_errorCode(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
869 {
870    offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h4501_errorCode, ett_h4501_errorCode, errorCode_choice, "errorCode", NULL);
871    return offset;
872 }
873
874
875 static int
876 dissect_h4501_parameter(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
877 {
878    /* TODO - decode return error parameter based on localErrorCode */
879    offset=dissect_per_octet_string(tvb, offset, pinfo, tree, hf_h4501_parameter, -1, -1, NULL, NULL);
880    return offset;
881 }
882
883
884 static per_sequence_t ReturnError_sequence[] = {
885         { "invokeID", NO_EXTENSIONS, NOT_OPTIONAL,
886                 dissect_h4501_invokeId },
887         { "errorCode", NO_EXTENSIONS, NOT_OPTIONAL,
888                 dissect_h4501_errorCode },
889         { "parameter", NO_EXTENSIONS, OPTIONAL,
890                 dissect_h4501_parameter },
891         { NULL, 0, 0, NULL }
892 };
893 static int
894 dissect_h4501_ReturnError(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
895 {
896    offset=dissect_per_sequence(tvb, offset, pinfo, tree, hf_h4501_ReturnError, ett_h4501_ReturnError, ReturnError_sequence);
897    return offset;
898 }
899
900
901 static const value_string GeneralProblem_vals[] = {
902    {  0, "unrecognizedCompenent"},
903    {  1, "mistypedCompenent"},
904    {  2, "badlyStructuredCompenent"},
905    {  0, NULL }
906 };
907 static int
908 dissect_h4501_GeneralProblem(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
909 {
910    offset=dissect_per_constrained_integer(tvb, offset, pinfo, tree, hf_h4501_GeneralProblem, 0, 2, NULL, NULL, FALSE);
911    return offset;
912 }
913
914
915 static const value_string InvokeProblem_vals[] = {
916    {  0, "duplicateInvocation"},
917    {  1, "unrecognizedOperation"},
918    {  2, "mistypedArgument"},
919    {  3, "resourceLimitation"},
920    {  4, "releaseInProgress"},
921    {  5, "unrecognizedLinkedId"},
922    {  6, "linkedResponseUnexpected"},
923    {  7, "unexpectedLinkedOperation"},
924    {  0, NULL }
925 };
926 static int
927 dissect_h4501_InvokeProblem(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
928 {
929    offset=dissect_per_constrained_integer(tvb, offset, pinfo, tree, hf_h4501_InvokeProblem, 0, 7, NULL, NULL, FALSE);
930    return offset;
931 }
932
933
934 static const value_string ReturnResultProblem_vals[] = {
935    {  0, "unrecognizedInvocation"},
936    {  1, "resultResponseUnexpected"},
937    {  2, "mistypedResult"},
938    {  0, NULL }
939 };
940 static int
941 dissect_h4501_ReturnResultProblem(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
942 {
943    offset=dissect_per_constrained_integer(tvb, offset, pinfo, tree, hf_h4501_ReturnResultProblem, 0, 2, NULL, NULL, FALSE);
944    return offset;
945 }
946
947
948 static const value_string ReturnErrorProblem_vals[] = {
949    {  0, "unrecognizedInvocation"},
950    {  1, "errorResponseUnexpected"},
951    {  2, "unrecognizedError"},
952    {  3, "unexpectedError"},
953    {  4, "mistypedParameter"},
954    {  0, NULL }
955 };
956 static int
957 dissect_h4501_ReturnErrorProblem(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
958 {
959    offset=dissect_per_constrained_integer(tvb, offset, pinfo, tree, hf_h4501_ReturnErrorProblem, 0, 4, NULL, NULL, FALSE);
960    return offset;
961 }
962
963
964 static const value_string problem_vals[] = {
965         { 0, "general" },
966         { 1, "invoke" },
967         { 2, "returnResult" },
968         { 3, "returnError" },
969         { 0, NULL}
970 };
971 static per_choice_t problem_choice[] = {
972         { 0, "general", NO_EXTENSIONS,
973                 dissect_h4501_GeneralProblem },
974         { 1, "invoke", NO_EXTENSIONS,
975                 dissect_h4501_InvokeProblem },
976         { 2, "returnResult", NO_EXTENSIONS,
977                 dissect_h4501_ReturnResultProblem },
978         { 3, "returnError", NO_EXTENSIONS,
979                 dissect_h4501_ReturnErrorProblem },
980         { 0, NULL, 0, NULL }
981 };
982 static int
983 dissect_h4501_problem(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
984 {
985    offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h4501_problem, ett_h4501_problem, problem_choice, "problem", NULL);
986    return offset;
987 }
988
989
990 static per_sequence_t Reject_sequence[] = {
991         { "invokeID", NO_EXTENSIONS, NOT_OPTIONAL,
992                 dissect_h4501_invokeId },
993         { "problem", NO_EXTENSIONS, NOT_OPTIONAL,
994                 dissect_h4501_problem },
995         { NULL, 0, 0, NULL }
996 };
997 static int
998 dissect_h4501_Reject(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
999 {
1000    offset=dissect_per_sequence(tvb, offset, pinfo, tree, hf_h4501_Reject, ett_h4501_Reject, Reject_sequence);
1001    return offset;
1002 }
1003
1004
1005 static const value_string ROS_vals[] = {
1006         { 1, "invoke" },
1007         { 2, "returnResult" },
1008         { 3, "returnError" },
1009         { 4, "reject" },
1010         { 0, NULL}
1011 };
1012 static per_choice_t ROS_choice[] = {
1013         { 1, "invoke", NO_EXTENSIONS,
1014                 dissect_h4501_Invoke },
1015         { 2, "returnResult", NO_EXTENSIONS,
1016                 dissect_h4501_ReturnResult },
1017         { 3, "returnError", NO_EXTENSIONS,
1018                 dissect_h4501_ReturnError },
1019         { 4, "reject", NO_EXTENSIONS,
1020                 dissect_h4501_Reject },
1021         { 0, NULL, 0, NULL }
1022 };
1023 static int
1024 dissect_h4501_ROS(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
1025 {
1026    offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h4501_ROS, ett_h4501_ROS, ROS_choice, "ROS", NULL);
1027    return offset;
1028 }
1029
1030
1031 static int
1032 dissect_h4501_rosApdus(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
1033 {
1034         offset=dissect_per_sequence_of(tvb, offset, pinfo, tree, hf_h4501_rosApdus, ett_h4501_rosApdus, dissect_h4501_ROS);
1035         return offset;
1036 }
1037
1038
1039 static const value_string ServiceApdus_vals[] = {
1040         { 0, "rosApdus" },
1041         { 0, NULL}
1042 };
1043 static per_choice_t ServiceApdus_choice[] = {
1044         { 0, "rosApdus", EXTENSION_ROOT, 
1045                 dissect_h4501_rosApdus },
1046         { 0, NULL, 0, NULL }
1047 };
1048 static int
1049 dissect_h4501_ServiceApdus(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
1050 {
1051    offset=dissect_per_choice(tvb, offset, pinfo, tree, hf_h4501_ServiceApdus, ett_h4501_ServiceApdus, ServiceApdus_choice, "ServiceApdus", NULL);
1052    return offset;
1053 }
1054
1055
1056 static per_sequence_t H4501_SupplementaryService_sequence[] = {
1057         { "networkFacilityExtension", EXTENSION_ROOT, OPTIONAL,
1058                 dissect_h4501_NetworkFacilityExtension },
1059         { "interpretationApdu", EXTENSION_ROOT, OPTIONAL,
1060                 dissect_h4501_InterpretationApdu },
1061         { "serviceApdu", EXTENSION_ROOT, NOT_OPTIONAL,
1062                 dissect_h4501_ServiceApdus },
1063         { NULL, 0, 0, NULL }
1064 };
1065 static void
1066 dissect_h4501(tvbuff_t *tvb, packet_info *pinfo, proto_tree* tree)
1067 {
1068    proto_item *it;
1069    proto_tree *tr;
1070    guint32 offset=0;
1071
1072    it=proto_tree_add_protocol_format(tree, proto_h4501, tvb, 0, tvb_length(tvb), "H.450.1");
1073    tr=proto_item_add_subtree(it, ett_h4501);
1074
1075    offset=dissect_per_sequence(tvb, offset, pinfo, tr, hf_h4501, ett_h4501, H4501_SupplementaryService_sequence);
1076 }
1077
1078
1079 void
1080 proto_register_h4501(void)
1081 {
1082         static hf_register_info hf[] =
1083         {
1084    { &hf_h4501,
1085       { "SupplementaryService", "h4501.SupplementaryService", FT_NONE, BASE_NONE,
1086       NULL, 0, "SupplementaryService sequence", HFILL }},
1087    { &hf_h4501_EntityType,
1088       { "EntityType", "h4501.EntityType", FT_UINT32, BASE_DEC,
1089       VALS(EntityType_vals), 0, "EntityType choice", HFILL }},
1090    { &hf_h4501_NetworkFacilityExtension,
1091       { "NetworkFacilityExtension", "h4501.NetworkFacilityExtension", FT_NONE, BASE_NONE,
1092       NULL, 0, "NetworkFacilityExtension sequence", HFILL }},
1093    { &hf_h4501_InterpretationApdu,
1094       { "InterpretationApdu", "h4501.InterpretationApdu", FT_UINT32, BASE_DEC,
1095       VALS(InterpretationApdu_vals), 0, "InterpretationApdu choice", HFILL }},
1096    { &hf_h4501_constrained_invokeId,
1097       { "invokeId", "h4501.invokeId", FT_UINT32, BASE_DEC,
1098       NULL, 0, "invokeId", HFILL }},
1099    { &hf_h4501_invokeId,
1100       { "invokeId", "h4501.invokeId", FT_INT32, BASE_DEC,
1101       NULL, 0, "invokeId", HFILL }},
1102    { &hf_h4501_localOpcode,
1103       { "opcode", "h4501.opcode", FT_INT32, BASE_DEC,
1104       VALS(localOpcode_vals), 0, "local", HFILL }},
1105    { &hf_h4501_globalCode,
1106       { "global", "h4501.global", FT_BYTES, BASE_HEX,
1107       NULL, 0, "global", HFILL }},
1108    { &hf_h4501_opcode,
1109       { "opcode", "h4501.opcode", FT_UINT32, BASE_DEC,
1110       VALS(opcode_vals), 0, "opcode choice", HFILL }},
1111    { &hf_h4502_CallIdentity,
1112       { "CallIdentity", "h4502.CallIdentity", FT_STRING, BASE_NONE,
1113       NULL, 0, "CallIdentity", HFILL }},
1114    { &hf_h4501_destinationAddress,
1115       { "destinationAddress", "h4501.destinationAddress", FT_NONE, BASE_NONE,
1116       NULL, 0, "destinationAddress sequence of", HFILL }},
1117    { &hf_h4501_EndpointAddress,
1118       { "EndpointAddress", "h4501.EndpointAddress", FT_NONE, BASE_NONE,
1119       NULL, 0, "EndpointAddress sequence of", HFILL }},
1120    { &hf_h4501_H225InformationElement,
1121       { "H225InformationElement", "h4501.H225InformationElement", FT_BYTES, BASE_HEX,
1122       NULL, 0, "H225InformationElement", HFILL }},
1123    { &hf_h4502_nonStandardData,
1124       { "nonStandardData", "h4502.nonStandardData", FT_NONE, BASE_NONE,
1125           NULL, 0, "NonStandardParameter SEQUENCE", HFILL }},
1126    { &hf_h4502_DummyArg,
1127       { "DummyArg", "h4502.DummyArg", FT_NONE, BASE_NONE,
1128       NULL, 0, "DummyArg sequence of", HFILL }},
1129    { &hf_h4502_CTInitiateArg,
1130       { "CTInitiateArg", "h4502.CTInitiateArg", FT_NONE, BASE_NONE,
1131       NULL, 0, "CTInitiateArg sequence of", HFILL }},
1132    { &hf_h4502_CTSetupArg,
1133       { "CTSetupArg", "h4502.CTSetupArg", FT_NONE, BASE_NONE,
1134       NULL, 0, "CTSetupArg sequence of", HFILL }},
1135         { &hf_h4502_redirectionInfo,
1136                 { "redirectionInfo", "h4502.redirectionInfo", FT_STRING, BASE_HEX,
1137                 NULL, 0, "redirectionInfo BMPString", HFILL }},
1138    { &hf_h4502_CTUpdateArg,
1139       { "CTUpdateArg", "h4502.CTUpdateArg", FT_NONE, BASE_NONE,
1140       NULL, 0, "CTUpdateArg sequence of", HFILL }},
1141    { &hf_h4501_SubaddressInformation,
1142                 { "SubaddressInformation", "h4501.SubaddressInformation", FT_BYTES, BASE_HEX,
1143                 NULL, 0, "SubaddressInformation octet string", HFILL }},
1144         { &hf_h4501_oddCountIndicator,
1145                 { "oddCountIndicator", "h4501.oddCountIndicator", FT_BOOLEAN, 8,
1146                 TFS(&tfs_oddCountIndicator_bit), 0x01, "The oddCountIndicator bit", HFILL }},
1147    { &hf_h4501_UserSpecifiedSubaddress,
1148       { "UserSpecifiedSubaddress", "h4501.UserSpecifiedSubaddress", FT_NONE, BASE_NONE,
1149       NULL, 0, "UserSpecifiedSubaddress sequence of", HFILL }},
1150    { &hf_h4501_NSAPAddress,
1151                 { "NSAPAddress", "h4501.NSAPAddress", FT_BYTES, BASE_HEX,
1152                 NULL, 0, "NSAPAddress octet string", HFILL }},
1153    { &hf_h4501_PartySubaddress,
1154       { "PartySubaddress", "h4501.PartySubaddress", FT_UINT32, BASE_DEC,
1155       VALS(PartySubaddress_vals), 0, "PartySubaddress choice", HFILL }},
1156    { &hf_h4502_SubaddressTransferArg,
1157       { "SubaddressTransferArg", "h4502.SubaddressTransferArg", FT_NONE, BASE_NONE,
1158       NULL, 0, "SubaddressTransferArg sequence of", HFILL }},
1159    { &hf_h4502_EndDesignation,
1160       { "EndDesignation", "h4502.EndDesignation", FT_UINT32, BASE_DEC,
1161       VALS(EndDesignation_vals), 0, "EndDesignation", HFILL }},
1162    { &hf_h4502_CallStatus,
1163       { "CallStatus", "h4502.CallStatus", FT_UINT32, BASE_DEC,
1164       VALS(CallStatus_vals), 0, "CallStatus", HFILL }},
1165    { &hf_h4502_CTCompleteArg,
1166       { "CTCompleteArg", "h4502.CTCompleteArg", FT_NONE, BASE_NONE,
1167       NULL, 0, "CTCompleteArg sequence of", HFILL }},
1168         { &hf_h4502_connectedInfo,
1169                 { "connectedInfo", "h4502.connectedInfo", FT_STRING, BASE_HEX,
1170                 NULL, 0, "connectedInfo BMPString", HFILL }},
1171    { &hf_h4502_CTActiveArg,
1172       { "CTActiveArg", "h4502.CTActiveArg", FT_NONE, BASE_NONE,
1173       NULL, 0, "CTActiveArg sequence of", HFILL }},
1174    { &hf_h4501_argumentExtension,
1175       { "argumentExtension", "h4501.argumentExtension", FT_BYTES, BASE_HEX,
1176       NULL, 0, "argumentExtension", HFILL }},
1177    { &hf_h4501_argument,
1178       { "argument", "h4501.argument", FT_BYTES, BASE_HEX,
1179       NULL, 0, "argument", HFILL }},
1180    { &hf_h4501_Invoke,
1181       { "Invoke", "h4501.Invoke", FT_NONE, BASE_NONE,
1182       NULL, 0, "Invoke sequence of", HFILL }},
1183    { &hf_h4502_CTIdentifyRes,
1184       { "CTIdentifyRes", "h4502.CTIdentifyRes", FT_NONE, BASE_NONE,
1185       NULL, 0, "CTIdentifyRes sequence of", HFILL }},
1186    { &hf_h4502_DummyRes,
1187       { "DummyRes", "h4502.DummyRes", FT_NONE, BASE_NONE,
1188       NULL, 0, "DummyRes sequence of", HFILL }},
1189    { &hf_h4501_resultExtension,
1190       { "resultExtension", "h4501.resultExtension", FT_BYTES, BASE_HEX,
1191       NULL, 0, "resultExtension", HFILL }},
1192    { &hf_h4501_ReturnResult_result,
1193       { "result", "h4501.ReturnResult.result", FT_BYTES, BASE_HEX,
1194       NULL, 0, "result", HFILL }},
1195    { &hf_h4501_result,
1196       { "result", "h4501.result", FT_NONE, BASE_NONE,
1197       NULL, 0, "result sequence of", HFILL }},
1198    { &hf_h4501_ReturnResult,
1199       { "ReturnResult", "h4501.ReturnResult", FT_NONE, BASE_NONE,
1200       NULL, 0, "ReturnResult sequence of", HFILL }},
1201    { &hf_h4501_localErrorCode,
1202       { "errorCode", "h4501.errorCode", FT_INT32, BASE_DEC,
1203       VALS(localErrorCode_vals), 0, "local", HFILL }},
1204    { &hf_h4501_errorCode,
1205       { "errorCode", "h4501.errorCode", FT_UINT32, BASE_DEC,
1206       VALS(errorCode_vals), 0, "errorCode", HFILL }},
1207    { &hf_h4501_parameter,
1208       { "parameter", "h4501.parameter", FT_BYTES, BASE_HEX,
1209       NULL, 0, "parameter", HFILL }},
1210    { &hf_h4501_ReturnError,
1211       { "ReturnError", "h4501.ReturnError", FT_NONE, BASE_NONE,
1212       NULL, 0, "ReturnError sequence of", HFILL }},
1213    { &hf_h4501_GeneralProblem,
1214       { "GeneralProblem", "h4501.GeneralProblem", FT_UINT32, BASE_DEC,
1215       VALS(GeneralProblem_vals), 0, "GeneralProblem", HFILL }},
1216    { &hf_h4501_InvokeProblem,
1217       { "InvokeProblem", "h4501.InvokeProblem", FT_UINT32, BASE_DEC,
1218       VALS(InvokeProblem_vals), 0, "InvokeProblem", HFILL }},
1219    { &hf_h4501_ReturnResultProblem,
1220       { "ReturnResultProblem", "h4501.ReturnResultProblem", FT_UINT32, BASE_DEC,
1221       VALS(ReturnResultProblem_vals), 0, "ReturnResultProblem", HFILL }},
1222    { &hf_h4501_ReturnErrorProblem,
1223       { "ReturnErrorProblem", "h4501.ReturnErrorProblem", FT_UINT32, BASE_DEC,
1224       VALS(ReturnErrorProblem_vals), 0, "ReturnErrorProblem", HFILL }},
1225    { &hf_h4501_problem,
1226       { "problem", "h4501.problem", FT_UINT32, BASE_DEC,
1227       VALS(problem_vals), 0, "problem choice", HFILL }},
1228    { &hf_h4501_Reject,
1229       { "Reject", "h4501.Reject", FT_NONE, BASE_NONE,
1230       NULL, 0, "Reject sequence of", HFILL }},
1231    { &hf_h4501_ROS,
1232       { "ROS", "h4501.ROS", FT_UINT32, BASE_DEC,
1233       VALS(ROS_vals), 0, "ROS choice", HFILL }},
1234    { &hf_h4501_rosApdus,
1235       { "rosApdus", "h4501.rosApdus", FT_NONE, BASE_NONE,
1236       NULL, 0, "rosApdus sequence of", HFILL }},
1237    { &hf_h4501_ServiceApdus,
1238       { "ServiceApdus", "h4501.ServiceApdus", FT_UINT32, BASE_DEC,
1239       VALS(ServiceApdus_vals), 0, "ServiceApdus choice", HFILL }}
1240    };
1241
1242         static gint *ett[] =
1243         {
1244       &ett_h4501,
1245       &ett_h4501_EntityType,
1246       &ett_h4501_NetworkFacilityExtension,
1247       &ett_h4501_InterpretationApdu,
1248       &ett_h4501_opcode,
1249       &ett_h4501_destinationAddress,
1250       &ett_h4501_EndpointAddress,
1251       &ett_h4501_PartySubaddress,
1252       &ett_h4501_argumentExtension,
1253       &ett_h4501_Invoke,
1254       &ett_h4501_resultExtension,
1255       &ett_h4501_result,
1256       &ett_h4501_ReturnResult,
1257       &ett_h4501_errorCode,
1258       &ett_h4501_ReturnError,
1259       &ett_h4501_problem,
1260       &ett_h4501_Reject,
1261       &ett_h4501_ROS,
1262       &ett_h4501_rosApdus,
1263       &ett_h4501_ServiceApdus,
1264
1265       &ett_h4502_DummyArg,
1266       &ett_h4502_CTInitiateArg,
1267       &ett_h4502_CTSetupArg,
1268       &ett_h4502_CTUpdateArg,
1269       &ett_h4502_SubaddressTransferArg,
1270       &ett_h4502_CTCompleteArg,
1271       &ett_h4502_CTActiveArg,
1272       &ett_h4502_CTIdentifyRes,
1273       &ett_h4502_DummyRes
1274    };
1275
1276    proto_h4501 = proto_register_protocol("H4501", "H4501", "h4501");
1277    proto_register_field_array(proto_h4501, hf, array_length(hf));
1278    proto_register_subtree_array(ett, array_length(ett));
1279    register_dissector("h4501", dissect_h4501, proto_h4501);
1280 }
1281
1282 void
1283 proto_reg_handoff_h4501(void)
1284 {
1285    h4501_handle=create_dissector_handle(dissect_h4501, proto_h4501);
1286 }