smb2-dissector: learn the "REPLAY_OPERATION" flag
[obnox/wireshark/wip.git] / epan / dissectors / packet-smpp.c
1 /* packet-smpp.c
2  * Routines for Short Message Peer to Peer dissection
3  * Copyright 2001, Tom Uijldert.
4  *
5  * Data Coding Scheme decoding for GSM (SMS and CBS),
6  * provided by Olivier Biot.
7  *
8  * Dissection of multiple SMPP PDUs within one packet
9  * provided by Chris Wilson.
10  *
11  * Statistics support using Stats Tree API
12  * provided by Abhik Sarkar
13  *
14  * Support for SMPP 5.0
15  * introduced by Abhik Sarkar
16  *
17  * Support for Huawei SMPP+ extensions
18  * introduced by Xu Bo and enhance by Abhik Sarkar
19  *
20  * Enhanced error code handling
21  * provided by Stipe Tolj from Kannel.
22  *
23  * $Id$
24  *
25  * Refer to the AUTHORS file or the AUTHORS section in the man page
26  * for contacting the author(s) of this file.
27  *
28  * Wireshark - Network traffic analyzer
29  * By Gerald Combs <gerald@wireshark.org>
30  * Copyright 1998 Gerald Combs
31  *
32  * This program is free software; you can redistribute it and/or
33  * modify it under the terms of the GNU General Public License
34  * as published by the Free Software Foundation; either version 2
35  * of the License, or (at your option) any later version.
36  *
37  * This program is distributed in the hope that it will be useful,
38  * but WITHOUT ANY WARRANTY; without even the implied warranty of
39  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
40  * GNU General Public License for more details.
41  *
42  * You should have received a copy of the GNU General Public License
43  * along with this program; if not, write to the Free Software
44  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
45  * ----------
46  *
47  * Dissector of an SMPP (Short Message Peer to Peer) PDU, as defined by the
48  * SMS forum (www.smsforum.net) in "SMPP protocol specification v3.4"
49  * (document version: 12-Oct-1999 Issue 1.2)
50  */
51
52 #ifdef HAVE_CONFIG_H
53 # include "config.h"
54 #endif
55
56 #include <stdio.h>
57 #include <stdlib.h>
58 #include <string.h>
59 #include <time.h>
60
61 #include <glib.h>
62
63 #include <epan/packet.h>
64 #include <epan/tap.h>
65 #include <epan/stats_tree.h>
66
67 #include <epan/prefs.h>
68 #include <epan/emem.h>
69 #include "packet-tcp.h"
70 #include "packet-smpp.h"
71
72 /* General-purpose debug logger.
73  * Requires double parentheses because of variable arguments of printf().
74  *
75  * Enable debug logging for SMPP by defining AM_CFLAGS
76  * so that it contains "-DDEBUG_smpp"
77  */
78 #ifdef DEBUG_smpp
79 #define DebugLog(x) \
80     g_print("%s:%u: ", __FILE__, __LINE__);     \
81     g_print x
82 #else
83 #define DebugLog(x) ;
84 #endif
85
86 #define SMPP_MIN_LENGTH 16
87
88 /* Forward declarations         */
89 static void dissect_smpp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
90 static guint get_smpp_pdu_len(packet_info *pinfo, tvbuff_t *tvb, int offset);
91 static void dissect_smpp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
92
93 /*
94  * Initialize the protocol and registered fields
95  *
96  * Fixed header section
97  */
98 static int proto_smpp                           = -1;
99
100 static int st_smpp_ops                          = -1;
101 static int st_smpp_req                          = -1;
102 static int st_smpp_res                          = -1;
103 static int st_smpp_res_status                   = -1;
104
105 static int hf_smpp_command_id                   = -1;
106 static int hf_smpp_command_length               = -1;
107 static int hf_smpp_command_status               = -1;
108 static int hf_smpp_sequence_number              = -1;
109
110 /*
111  * Fixed body section
112  */
113 static int hf_smpp_system_id                    = -1;
114 static int hf_smpp_password                     = -1;
115 static int hf_smpp_system_type                  = -1;
116 static int hf_smpp_interface_version            = -1;
117 static int hf_smpp_addr_ton                     = -1;
118 static int hf_smpp_addr_npi                     = -1;
119 static int hf_smpp_address_range                = -1;
120 static int hf_smpp_service_type                 = -1;
121 static int hf_smpp_source_addr_ton              = -1;
122 static int hf_smpp_source_addr_npi              = -1;
123 static int hf_smpp_source_addr                  = -1;
124 static int hf_smpp_dest_addr_ton                = -1;
125 static int hf_smpp_dest_addr_npi                = -1;
126 static int hf_smpp_destination_addr             = -1;
127 static int hf_smpp_esm_submit_msg_mode          = -1;
128 static int hf_smpp_esm_submit_msg_type          = -1;
129 static int hf_smpp_esm_submit_features          = -1;
130 static int hf_smpp_protocol_id                  = -1;
131 static int hf_smpp_priority_flag                = -1;
132 static int hf_smpp_schedule_delivery_time       = -1;
133 static int hf_smpp_schedule_delivery_time_r     = -1;
134 static int hf_smpp_validity_period              = -1;
135 static int hf_smpp_validity_period_r            = -1;
136 static int hf_smpp_regdel_receipt               = -1;
137 static int hf_smpp_regdel_acks                  = -1;
138 static int hf_smpp_regdel_notif                 = -1;
139 static int hf_smpp_replace_if_present_flag      = -1;
140 static int hf_smpp_data_coding                  = -1;
141 static int hf_smpp_sm_default_msg_id            = -1;
142 static int hf_smpp_sm_length                    = -1;
143 static int hf_smpp_short_message                = -1;
144 static int hf_smpp_message_id                   = -1;
145 static int hf_smpp_dlist                        = -1;
146 static int hf_smpp_dlist_resp                   = -1;
147 static int hf_smpp_dl_name                      = -1;
148 static int hf_smpp_final_date                   = -1;
149 static int hf_smpp_final_date_r                 = -1;
150 static int hf_smpp_message_state                = -1;
151 static int hf_smpp_error_code                   = -1;
152 static int hf_smpp_error_status_code            = -1;
153 static int hf_smpp_esme_addr_ton                = -1;
154 static int hf_smpp_esme_addr_npi                = -1;
155 static int hf_smpp_esme_addr                    = -1;
156
157 /*
158  * Optional parameter section
159  */
160 static int hf_smpp_opt_params                   = -1;
161 static int hf_smpp_opt_param                    = -1;
162 static int hf_smpp_opt_param_tag                = -1;
163 static int hf_smpp_opt_param_len                = -1;
164 static int hf_smpp_vendor_op                    = -1;
165 static int hf_smpp_reserved_op                  = -1;
166
167 static int hf_smpp_dest_addr_subunit            = -1;
168 static int hf_smpp_dest_network_type            = -1;
169 static int hf_smpp_dest_bearer_type             = -1;
170 static int hf_smpp_dest_telematics_id           = -1;
171 static int hf_smpp_source_addr_subunit          = -1;
172 static int hf_smpp_source_network_type          = -1;
173 static int hf_smpp_source_bearer_type           = -1;
174 static int hf_smpp_source_telematics_id         = -1;
175 static int hf_smpp_qos_time_to_live             = -1;
176 static int hf_smpp_payload_type                 = -1;
177 static int hf_smpp_additional_status_info_text  = -1;
178 static int hf_smpp_receipted_message_id         = -1;
179 static int hf_smpp_msg_wait_ind                 = -1;
180 static int hf_smpp_msg_wait_type                = -1;
181 static int hf_smpp_privacy_indicator            = -1;
182 static int hf_smpp_source_subaddress            = -1;
183 static int hf_smpp_dest_subaddress              = -1;
184 static int hf_smpp_user_message_reference       = -1;
185 static int hf_smpp_user_response_code           = -1;
186 static int hf_smpp_source_port                  = -1;
187 static int hf_smpp_destination_port             = -1;
188 static int hf_smpp_sar_msg_ref_num              = -1;
189 static int hf_smpp_language_indicator           = -1;
190 static int hf_smpp_sar_total_segments           = -1;
191 static int hf_smpp_sar_segment_seqnum           = -1;
192 static int hf_smpp_SC_interface_version         = -1;
193 static int hf_smpp_callback_num_pres            = -1;
194 static int hf_smpp_callback_num_scrn            = -1;
195 static int hf_smpp_callback_num_atag            = -1;
196 static int hf_smpp_number_of_messages           = -1;
197 static int hf_smpp_callback_num                 = -1;
198 static int hf_smpp_dpf_result                   = -1;
199 static int hf_smpp_set_dpf                      = -1;
200 static int hf_smpp_ms_availability_status       = -1;
201 static int hf_smpp_network_error_type           = -1;
202 static int hf_smpp_network_error_code           = -1;
203 static int hf_smpp_message_payload              = -1;
204 static int hf_smpp_delivery_failure_reason      = -1;
205 static int hf_smpp_more_messages_to_send        = -1;
206 static int hf_smpp_ussd_service_op              = -1;
207 static int hf_smpp_display_time                 = -1;
208 static int hf_smpp_sms_signal                   = -1;
209 static int hf_smpp_ms_validity                  = -1;
210 static int hf_smpp_alert_on_message_delivery_null       = -1;
211 static int hf_smpp_alert_on_message_delivery    = -1;
212 static int hf_smpp_its_reply_type               = -1;
213 static int hf_smpp_its_session_number           = -1;
214 static int hf_smpp_its_session_sequence         = -1;
215 static int hf_smpp_its_session_ind              = -1;
216
217 /* Optional Parameters introduced in SMPP 5.0   */
218 static int hf_smpp_congestion_state             = -1;
219 static int hf_smpp_billing_identification       = -1;
220 static int hf_smpp_dest_addr_np_country         = -1;
221 static int hf_smpp_dest_addr_np_information     = -1;
222 static int hf_smpp_dest_addr_np_resolution      = -1;
223 static int hf_smpp_source_network_id            = -1;
224 static int hf_smpp_source_node_id               = -1;
225 static int hf_smpp_dest_network_id              = -1;
226 static int hf_smpp_dest_node_id                 = -1;
227 /* Optional Parameters for Cell Broadcast Operations */
228 static int hf_smpp_broadcast_channel_indicator  = -1;
229 static int hf_smpp_broadcast_content_type_nw    = -1;
230 static int hf_smpp_broadcast_content_type_type  = -1;
231 static int hf_smpp_broadcast_content_type_info  = -1;
232 static int hf_smpp_broadcast_message_class      = -1;
233 static int hf_smpp_broadcast_rep_num            = -1;
234 static int hf_smpp_broadcast_frequency_interval_unit    = -1;
235 static int hf_smpp_broadcast_frequency_interval_value   = -1;
236 static int hf_smpp_broadcast_area_identifier    = -1;
237 static int hf_smpp_broadcast_area_identifier_format     = -1;
238 static int hf_smpp_broadcast_error_status       = -1;
239 static int hf_smpp_broadcast_area_success       = -1;
240 static int hf_smpp_broadcast_end_time           = -1;
241 static int hf_smpp_broadcast_end_time_r         = -1;
242 static int hf_smpp_broadcast_service_group      = -1;
243
244 /*
245  * Data Coding Scheme section
246  */
247 static int hf_smpp_dcs = -1;
248 static int hf_smpp_dcs_sms_coding_group = -1;
249 static int hf_smpp_dcs_text_compression = -1;
250 static int hf_smpp_dcs_class_present = -1;
251 static int hf_smpp_dcs_charset = -1;
252 static int hf_smpp_dcs_class = -1;
253 static int hf_smpp_dcs_cbs_coding_group = -1;
254 static int hf_smpp_dcs_cbs_language = -1;
255 static int hf_smpp_dcs_wap_charset = -1;
256 static int hf_smpp_dcs_wap_class = -1;
257 static int hf_smpp_dcs_cbs_class = -1;
258
259 /*
260  * Huawei SMPP+ extensions
261  */
262 static int hf_huawei_smpp_version                        = -1;
263 static int hf_huawei_smpp_smsc_addr                        = -1;
264 static int hf_huawei_smpp_msc_addr_noa                        = -1;
265 static int hf_huawei_smpp_msc_addr_npi                        = -1;
266 static int hf_huawei_smpp_msc_addr                        = -1;
267 static int hf_huawei_smpp_mo_mt_flag                        = -1;
268 static int hf_huawei_smpp_length_auth                        = -1;
269 static int hf_huawei_smpp_sm_id                                = -1;
270 static int hf_huawei_smpp_service_id                        = -1;
271 static int hf_huawei_smpp_operation_result                = -1;
272 static int hf_huawei_smpp_notify_mode                        = -1;
273 static int hf_huawei_smpp_delivery_result                = -1;
274
275 /* Initialize the subtree pointers */
276 static gint ett_smpp            = -1;
277 static gint ett_dlist           = -1;
278 static gint ett_dlist_resp      = -1;
279 static gint ett_opt_params      = -1;
280 static gint ett_opt_param       = -1;
281 static gint ett_dcs             = -1;
282
283 /* Reassemble SMPP TCP segments */
284 static gboolean reassemble_over_tcp = TRUE;
285
286 /* Tap */
287 static int smpp_tap             = -1;
288
289 /*
290  * Value-arrays for field-contents
291  */
292 static const value_string vals_command_id[] = {         /* Operation    */
293     { 0x80000000, "Generic_nack" },
294     { 0x00000001, "Bind_receiver" },
295     { 0x80000001, "Bind_receiver - resp" },
296     { 0x00000002, "Bind_transmitter" },
297     { 0x80000002, "Bind_transmitter - resp" },
298     { 0x00000003, "Query_sm" },
299     { 0x80000003, "Query_sm - resp" },
300     { 0x00000004, "Submit_sm" },
301     { 0x80000004, "Submit_sm - resp" },
302     { 0x00000005, "Deliver_sm" },
303     { 0x80000005, "Deliver_sm - resp" },
304     { 0x00000006, "Unbind" },
305     { 0x80000006, "Unbind - resp" },
306     { 0x00000007, "Replace_sm" },
307     { 0x80000007, "Replace_sm - resp" },
308     { 0x00000008, "Cancel_sm" },
309     { 0x80000008, "Cancel_sm - resp" },
310     { 0x00000009, "Bind_transceiver" },
311     { 0x80000009, "Bind_transceiver - resp" },
312     { 0x0000000B, "Outbind" },
313     { 0x00000015, "Enquire_link" },
314     { 0x80000015, "Enquire_link - resp" },
315     { 0x00000021, "Submit_multi" },
316     { 0x80000021, "Submit_multi - resp" },
317     { 0x00000102, "Alert_notification" },
318     { 0x00000103, "Data_sm" },
319     { 0x80000103, "Data_sm - resp" },
320     /* Introduced in SMPP 5.0 */
321     { 0x00000111, "Broadcast_sm" },
322     { 0x80000111, "Broadcast_sm - resp" },
323     { 0x00000112, "Query_broadcast_sm" },
324     { 0x80000112, "Query_broadcast_sm - resp" },
325     { 0x00000113, "Cancel_broadcast_sm" },
326     { 0x80000113, "Cancel_broadcast_sm - resp" },
327     /* Huawei SMPP+ extensions */
328     { 0x01000001, "Auth_acc" },
329     { 0x81000001, "Auth_acc - resp" },
330     { 0X01000002, "Sm_result_notify" },
331     { 0X81000002, "Sm_result_notify - resp" },
332     { 0, NULL }
333 };
334
335 static const value_string vals_command_status[] = {     /* Status       */
336     { 0x00000000, "Ok" },
337     { 0x00000001, "Message length is invalid" },
338     { 0x00000002, "Command length is invalid" },
339     { 0x00000003, "Invalid command ID" },
340     { 0x00000004, "Incorrect BIND status for given command" },
341     { 0x00000005, "ESME already in bound state" },
342     { 0x00000006, "Invalid priority flag" },
343     { 0x00000007, "Invalid registered delivery flag" },
344     { 0x00000008, "System error" },
345     { 0x00000009, "[Reserved]" },
346     { 0x0000000A, "Invalid source address" },
347     { 0x0000000B, "Invalid destination address" },
348     { 0x0000000C, "Message ID is invalid" },
349     { 0x0000000D, "Bind failed" },
350     { 0x0000000E, "Invalid password" },
351     { 0x0000000F, "Invalid system ID" },
352     { 0x00000010, "[Reserved]" },
353     { 0x00000011, "Cancel SM failed" },
354     { 0x00000012, "[Reserved]" },
355     { 0x00000013, "Replace SM failed" },
356     { 0x00000014, "Message queue full" },
357     { 0x00000015, "Invalid service type" },
358     { 0x00000033, "Invalid number of destinations" },
359     { 0x00000034, "Invalid distribution list name" },
360     { 0x00000040, "Destination flag is invalid (submit_multi)" },
361     { 0x00000041, "[Reserved]" },
362     { 0x00000042, "Invalid 'submit with replace' request" },
363     { 0x00000043, "Invalid esm_class field data" },
364     { 0x00000044, "Cannot submit to distribution list" },
365     { 0x00000045, "submit_sm or submit_multi failed" },
366     { 0x00000046, "[Reserved]" },
367     { 0x00000047, "[Reserved]" },
368     { 0x00000048, "Invalid source address TON" },
369     { 0x00000049, "Invalid source address NPI" },
370     { 0x00000050, "Invalid destination address TON" },
371     { 0x00000051, "Invalid destination address NPI" },
372     { 0x00000052, "[Reserved]" },
373     { 0x00000053, "Invalid system_type field" },
374     { 0x00000054, "Invalid replace_if_present flag" },
375     { 0x00000055, "Invalid number of messages" },
376     { 0x00000056, "[Reserved]" },
377     { 0x00000057, "[Reserved]" },
378     { 0x00000058, "Throttling error (ESME exceeded allowed message limits)" },
379     { 0x00000059, "[Reserved]" },
380     { 0x00000060, "[Reserved]" },
381     { 0x00000061, "Invalid scheduled delivery time" },
382     { 0x00000062, "Invalid message validity period (expiry time)" },
383     { 0x00000063, "Predefined message invalid or not found" },
384     { 0x00000064, "ESME receiver temporary app error code" },
385     { 0x00000065, "ESME receiver permanent app error code" },
386     { 0x00000066, "ESME receiver reject message error code" },
387     { 0x00000067, "query_sm request failed" },
388     { 0x000000C0, "Error in the optional part of the PDU body" },
389     { 0x000000C1, "Optional parameter not allowed" },
390     { 0x000000C2, "Invalid parameter length" },
391     { 0x000000C3, "Expected optional parameter missing" },
392     { 0x000000C4, "Invalid optional parameter  value" },
393     { 0x000000FE, "(Transaction) Delivery failure (used for data_sm_resp)" },
394     { 0x000000FF, "Unknown error" },
395     /* Introduced in SMPP 5.0 */
396     { 0x00000100, "ESME Not authorised to use specified service_type." },
397     { 0x00000101, "ESME Prohibited from using specified operation."},
398     { 0x00000102, "Specified service_type is unavailable." },
399     { 0x00000103, "Specified service_type is denied." },
400     { 0x00000104, "Invalid Data Coding Scheme." },
401     { 0x00000105, "Source Address Sub unit is Invalid." },
402     { 0x00000106, "Destination Address Sub unit is Invalid." },
403     { 0x00000107, "Broadcast Frequency Interval is invalid." },
404     { 0x00000108, "Broadcast Alias Name is invalid." },
405     { 0x00000109, "Broadcast Area Format is invalid." },
406     { 0x0000010A, "Number of Broadcast Areas is invalid." },
407     { 0x0000010B, "Broadcast Content Type is invalid." },
408     { 0x0000010C, "Broadcast Message Class is invalid." },
409     { 0x0000010D, "broadcast_sm operation failed." },
410     { 0x0000010E, "query_broadcast_sm operation failed." },
411     { 0x0000010F, "cancel_broadcast_sm operation failed." },
412     { 0x00000110, "Number of Repeated Broadcasts is invalid." },
413     { 0x00000111, "Broadcast Service Group is invalid." },
414     { 0x00000112, "Broadcast Channel Indicator is invalid." },
415     { 0, NULL }
416 };
417
418 static const range_string reserved_command_status[] = {     /* Reserved ranges */
419     { 0x00000016, 0x00000032, "[Reserved]" },
420     { 0x00000035, 0x0000003F, "[Reserved]" },
421     { 0x00000068, 0x000000BF, "[Reserved]" },
422     { 0x000000C5, 0x000000FD, "[Reserved]" },
423     { 0x00000400, 0x000004FF, "[Message center vendor-specific error code]" },
424     { 0x00000500, 0xFFFFFFFF, "[Reserved]" },
425     { 0, 0, NULL }
426 };
427
428 static const value_string vals_tlv_tags[] = {
429     { 0x0005, "dest_addr_subunit" },
430     { 0x0006, "dest_network_type" },
431     { 0x0007, "dest_bearer_type" },
432     { 0x0008, "dest_telematics_id" },
433     { 0x000D, "source_addr_subunit" },
434     { 0x000E, "source_network_type" },
435     { 0x000F, "source_bearer_type" },
436     { 0x0010, "source_telematics_id" },
437     { 0x0017, "qos_time_to_live" },
438     { 0x0019, "payload_type" },
439     { 0x001D, "additional_status_info_text" },
440     { 0x001E, "receipted_message_id" },
441     { 0x0030, "ms_msg_wait_facilities" },
442     { 0x0201, "privacy_indicator" },
443     { 0x0202, "source_subaddress" },
444     { 0x0203, "dest_subaddress" },
445     { 0x0204, "user_message_reference" },
446     { 0x0205, "user_response_code" },
447     { 0x020A, "source_port" },
448     { 0x020B, "dest_port" },
449     { 0x020C, "sar_msg_ref_num" },
450     { 0x020D, "language_indicator" },
451     { 0x020E, "sar_total_segments" },
452     { 0x020F, "sar_segment_seqnum" },
453     { 0x0210, "sc_interface_version" },
454     { 0x0302, "callback_num_pres_ind" },
455     { 0x0303, "callback_num_atag" },
456     { 0x0304, "number_of_messages" },
457     { 0x0381, "callback_num" },
458     { 0x0420, "dpf_result" },
459     { 0x0421, "set_dpf" },
460     { 0x0422, "ms_availability_status" },
461     { 0x0423, "network_error_code" },
462     { 0x0424, "message_payload" },
463     { 0x0425, "delivery_failure_reason" },
464     { 0x0426, "more_messages_to_send" },
465     { 0x0427, "message_state" },
466     { 0x0428, "congestion_state" },
467     { 0x0501, "ussd_service_op" },
468     { 0x0600, "broadcast_channel_indicator" },
469     { 0x0601, "broadcast_content_type" },
470     { 0x0602, "broadcast_content_type_info" },
471     { 0x0603, "broadcast_message_class" },
472     { 0x0604, "broadcast_rep_num" },
473     { 0x0605, "broadcast_frequency_interval" },
474     { 0x0606, "broadcast_area_identifier" },
475     { 0x0607, "broadcast_error_status" },
476     { 0x0608, "broadcast_area_success" },
477     { 0x0609, "broadcast_end_time" },
478     { 0x060A, "broadcast_service_group" },
479     { 0x060B, "billing_identification" },
480     { 0x060D, "source_network_id" },
481     { 0x060E, "dest_network_id" },
482     { 0x060F, "source_node_id" },
483     { 0x0610, "dest_node_id" },
484     { 0x0611, "dest_addr_np_resolution" },
485     { 0x0612, "dest_addr_np_information" },
486     { 0x0613, "dest_addr_np_country" },
487     { 0x1201, "display_time" },
488     { 0x1203, "sms_signal" },
489     { 0x1204, "ms_validity" },
490     { 0x130C, "alert_on_message_delivery" },
491     { 0x1380, "its_reply_type" },
492     { 0x1383, "its_session_info" },
493     { 0, NULL }
494 };
495
496 static const value_string vals_addr_ton[] = {
497     { 0, "Unknown" },
498     { 1, "International" },
499     { 2, "National" },
500     { 3, "Network specific" },
501     { 4, "Subscriber number" },
502     { 5, "Alphanumeric" },
503     { 6, "Abbreviated" },
504     { 0, NULL }
505 };
506
507 static const value_string vals_addr_npi[] = {
508     {  0, "Unknown" },
509     {  1, "ISDN (E163/E164)" },
510     {  3, "Data (X.121)" },
511     {  4, "Telex (F.69)" },
512     {  6, "Land mobile (E.212)" },
513     {  8, "National" },
514     {  9, "Private" },
515     { 10, "ERMES" },
516     { 14, "Internet (IP)" },
517     { 18, "WAP client Id" },
518     {  0, NULL }
519 };
520
521 static const value_string vals_esm_submit_msg_mode[] = {
522     {  0x0, "Default SMSC mode" },
523     {  0x1, "Datagram mode" },
524     {  0x2, "Forward mode" },
525     {  0x3, "Store and forward mode" },
526     {  0, NULL }
527 };
528
529 static const value_string vals_esm_submit_msg_type[] = {
530     {  0x0, "Default message type" },
531     {  0x1, "Short message contains SMSC Delivery Receipt" },
532     {  0x2, "Short message contains (E)SME delivery acknowledgement" },
533     {  0x3, "Reserved" },
534     {  0x4, "Short message contains (E)SME manual/user acknowledgement" },
535     {  0x5, "Reserved" },
536     {  0x6, "Short message contains conversation abort" },
537     {  0x7, "Reserved" },
538     {  0x8, "Short message contains intermediate delivery notification" },
539     {  0, NULL }
540 };
541
542 static const value_string vals_esm_submit_features[] = {
543     {  0x0, "No specific features selected" },
544     {  0x1, "UDHI indicator" },
545     {  0x2, "Reply path" },
546     {  0x3, "UDHI and reply path" },
547     {  0, NULL }
548 };
549
550 static const value_string vals_priority_flag[] = {
551     {  0, "GSM: None      ANSI-136: Bulk         IS-95: Normal" },
552     {  1, "GSM: priority  ANSI-136: Normal       IS-95: Interactive" },
553     {  2, "GSM: priority  ANSI-136: Urgent       IS-95: Urgent" },
554     {  3, "GSM: priority  ANSI-136: Very Urgent  IS-95: Emergency" },
555     {  0, NULL }
556 };
557
558 static const value_string vals_regdel_receipt[] = {
559     {  0x0, "No SMSC delivery receipt requested" },
560     {  0x1, "Delivery receipt requested (for success or failure)" },
561     {  0x2, "Delivery receipt requested (for failure)" },
562     {  0x3, "Reserved in version <= 3.4; Delivery receipt requested (for success) in 5.0" },
563     {  0, NULL }
564 };
565
566 static const value_string vals_regdel_acks[] = {
567     {  0x0, "No recipient SME acknowledgement requested" },
568     {  0x1, "SME delivery acknowledgement requested" },
569     {  0x2, "SME manual/user acknowledgement requested" },
570     {  0x3, "Both delivery and manual/user acknowledgement requested" },
571     {  0, NULL }
572 };
573
574 static const value_string vals_regdel_notif[] = {
575     {  0x0, "No intermediate notification requested" },
576     {  0x1, "Intermediate notification requested" },
577     {  0, NULL }
578 };
579
580 static const value_string vals_replace_if_present_flag[] = {
581     {  0x0, "Don't replace" },
582     {  0x1, "Replace" },
583     {  0, NULL }
584 };
585
586 static const value_string vals_data_coding[] = {
587     {  0, "SMSC default alphabet" },
588     {  1, "IA5 (CCITT T.50/ASCII (ANSI X3.4)" },
589     {  2, "Octet unspecified (8-bit binary)" },
590     {  3, "Latin 1 (ISO-8859-1)" },
591     {  4, "Octet unspecified (8-bit binary)" },
592     {  5, "JIS (X 0208-1990)" },
593     {  6, "Cyrillic (ISO-8859-5)" },
594     {  7, "Latin/Hebrew (ISO-8859-8)" },
595     {  8, "UCS2 (ISO/IEC-10646)" },
596     {  9, "Pictogram encoding" },
597     {  10, "ISO-2022-JP (Music codes)" },
598     {  11, "reserved" },
599     {  12, "reserved" },
600     {  13, "Extended Kanji JIS(X 0212-1990)" },
601     {  14, "KS C 5601" },
602     /*! \TODO Rest to be defined (bitmask?) according GSM 03.38 */
603     {  0, NULL }
604 };
605
606 static const value_string vals_message_state[] = {
607     {  1, "ENROUTE" },
608     {  2, "DELIVERED" },
609     {  3, "EXPIRED" },
610     {  4, "DELETED" },
611     {  5, "UNDELIVERABLE" },
612     {  6, "ACCEPTED" },
613     {  7, "UNKNOWN" },
614     {  8, "REJECTED" },
615     {  0, NULL }
616 };
617
618 static const value_string vals_addr_subunit[] = {
619     {  0, "Unknown -default-" },
620     {  1, "MS Display" },
621     {  2, "Mobile equipment" },
622     {  3, "Smart card 1" },
623     {  4, "External unit 1" },
624     {  0, NULL }
625 };
626
627 static const value_string vals_network_type[] = {
628     {  0, "Unknown" },
629     {  1, "GSM" },
630     {  2, "ANSI-136/TDMA" },
631     {  3, "IS-95/CDMA" },
632     {  4, "PDC" },
633     {  5, "PHS" },
634     {  6, "iDEN" },
635     {  7, "AMPS" },
636     {  8, "Paging network" },
637     {  0, NULL }
638 };
639
640 static const value_string vals_bearer_type[] = {
641     {  0, "Unknown" },
642     {  1, "SMS" },
643     {  2, "Circuit Switched Data (CSD)" },
644     {  3, "Packet data" },
645     {  4, "USSD" },
646     {  5, "CDPD" },
647     {  6, "DataTAC" },
648     {  7, "FLEX/ReFLEX" },
649     {  8, "Cell Broadcast" },
650     {  0, NULL }
651 };
652
653 static const value_string vals_payload_type[] = {
654     {  0, "Default" },
655     {  1, "WCMP message" },
656     {  0, NULL }
657 };
658
659 static const value_string vals_privacy_indicator[] = {
660     {  0, "Not restricted -default-" },
661     {  1, "Restricted" },
662     {  2, "Confidential" },
663     {  3, "Secret" },
664     {  0, NULL }
665 };
666
667 static const value_string vals_language_indicator[] = {
668     {  0, "Unspecified -default-" },
669     {  1, "english" },
670     {  2, "french" },
671     {  3, "spanish" },
672     {  4, "german" },
673     {  5, "portuguese" },
674     {  0, NULL }
675 };
676
677 static const value_string vals_display_time[] = {
678     {  0, "Temporary" },
679     {  1, "Default -default-" },
680     {  2, "Invoke" },
681     {  0, NULL }
682 };
683
684 static const value_string vals_ms_validity[] = {
685     {  0, "Store indefinitely -default-" },
686     {  1, "Power down" },
687     {  2, "SID based registration area" },
688     {  3, "Display only" },
689     {  0, NULL }
690 };
691
692 static const value_string vals_dpf_result[] = {
693     {  0, "DPF not set" },
694     {  1, "DPF set" },
695     {  0, NULL }
696 };
697
698 static const value_string vals_set_dpf[] = {
699     {  0, "Not requested (Set DPF for delivery failure)" },
700     {  1, "Requested (Set DPF for delivery failure)" },
701     {  0, NULL }
702 };
703
704 static const value_string vals_ms_availability_status[] = {
705     {  0, "Available -default-" },
706     {  1, "Denied" },
707     {  2, "Unavailable" },
708     {  0, NULL }
709 };
710
711 static const value_string vals_delivery_failure_reason[] = {
712     {  0, "Destination unavailable" },
713     {  1, "Destination address invalid" },
714     {  2, "Permanent network error" },
715     {  3, "Temporary network error" },
716     {  0, NULL }
717 };
718
719 static const value_string vals_more_messages_to_send[] = {
720     {  0, "No more messages" },
721     {  1, "More messages -default-" },
722     {  0, NULL }
723 };
724
725 static const value_string vals_its_reply_type[] = {
726     {  0, "Digit" },
727     {  1, "Number" },
728     {  2, "Telephone no." },
729     {  3, "Password" },
730     {  4, "Character line" },
731     {  5, "Menu" },
732     {  6, "Date" },
733     {  7, "Time" },
734     {  8, "Continue" },
735     {  0, NULL }
736 };
737
738 static const value_string vals_ussd_service_op[] = {
739     {  0, "PSSD indication" },
740     {  1, "PSSR indication" },
741     {  2, "USSR request" },
742     {  3, "USSN request" },
743     { 16, "PSSD response" },
744     { 17, "PSSR response" },
745     { 18, "USSR confirm" },
746     { 19, "USSN confirm" },
747     {  0, NULL }
748 };
749
750 static const value_string vals_msg_wait_ind[] = {
751     {  0, "Set indication inactive" },
752     {  1, "Set indication active" },
753     {  0, NULL }
754 };
755
756 static const value_string vals_msg_wait_type[] = {
757     {  0, "Voicemail message waiting" },
758     {  1, "Fax message waiting" },
759     {  2, "Electronic mail message waiting" },
760     {  3, "Other message waiting" },
761     {  0, NULL }
762 };
763
764 static const value_string vals_callback_num_pres[] = {
765     {  0, "Presentation allowed" },
766     {  1, "Presentation restricted" },
767     {  2, "Number not available" },
768     {  3, "[Reserved]" },
769     {  0, NULL }
770 };
771
772 static const value_string vals_callback_num_scrn[] = {
773     {  0, "User provided, not screened" },
774     {  1, "User provided, verified and passed" },
775     {  2, "User provided, verified and failed" },
776     {  3, "Network provided" },
777     {  0, NULL }
778 };
779
780 static const value_string vals_network_error_type[] = {
781     {  1, "ANSI-136 (Access Denied Reason)" },
782     {  2, "IS-95 (Access Denied Reason)" },
783     {  3, "GSM" },
784     {  4, "[Reserved] in <= 3.4; ANSI 136 Cause Code in 5.0" },
785     {  5, "[Reserved] in <= 3.4; IS 95 Cause Code in 5.0" },
786     {  6, "[Reserved] in <= 3.4; ANSI-41 Error in 5.0" },
787     {  7, "[Reserved] in <= 3.4; SMPP Error in 5.0" },
788     {  8, "[Reserved] in <= 3.4; Message Center Specific in 5.0" },
789     {  0, NULL }
790 };
791
792 static const value_string vals_its_session_ind[] = {
793     {  0, "End of session indicator inactive" },
794     {  1, "End of session indicator active" },
795     {  0, NULL }
796 };
797
798 /* Data Coding Scheme: see 3GPP TS 23.040 and 3GPP TS 23.038 */
799 static const value_string vals_dcs_sms_coding_group[] = {
800     { 0x00, "SMS DCS: General Data Coding indication - Uncompressed text, no message class" },
801     { 0x01, "SMS DCS: General Data Coding indication - Uncompressed text" },
802     { 0x02, "SMS DCS: General Data Coding indication - Compressed text, no message class" },
803     { 0x03, "SMS DCS: General Data Coding indication - Compressed text" },
804     { 0x04, "SMS DCS: Message Marked for Automatic Deletion - Uncompressed text, no message class" },
805     { 0x05, "SMS DCS: Message Marked for Automatic Deletion - Uncompressed text" },
806     { 0x06, "SMS DCS: Message Marked for Automatic Deletion - Compressed text, no message class" },
807     { 0x07, "SMS DCS: Message Marked for Automatic Deletion - Compressed text" },
808     { 0x08, "SMS DCS: Reserved" },
809     { 0x09, "SMS DCS: Reserved" },
810     { 0x0A, "SMS DCS: Reserved" },
811     { 0x0B, "SMS DCS: Reserved" },
812     { 0x0C, "SMS DCS: Message Waiting Indication - Discard Message" },
813     { 0x0D, "SMS DCS: Message Waiting Indication - Store Message (GSM 7-bit default alphabet)" },
814     { 0x0E, "SMS DCS: Message Waiting Indication - Store Message (UCS-2 character set)" },
815     { 0x0F, "SMS DCS: Data coding / message class" },
816     { 0x00, NULL }
817 };
818
819 static const true_false_string tfs_dcs_text_compression = {
820     "Compressed text",
821     "Uncompressed text"
822 };
823
824 static const true_false_string tfs_dcs_class_present = {
825     "Message class is present",
826     "No message class"
827 };
828
829 static const value_string vals_dcs_charset[] = {
830     { 0x00, "GSM 7-bit default alphabet" },
831     { 0x01, "8-bit data" },
832     { 0x02, "UCS-2 (16-bit) data" },
833     { 0x03, "Reserved" },
834     { 0x00, NULL }
835 };
836
837 static const value_string vals_dcs_class[] = {
838     { 0x00, "Class 0" },
839     { 0x01, "Class 1 - ME specific" },
840     { 0x02, "Class 2 - (U)SIM specific" },
841     { 0x03, "Class 3 - TE specific" },
842     { 0x00, NULL }
843 };
844
845 static const value_string vals_dcs_cbs_coding_group[] = {
846     { 0x00, "CBS DCS: Language using the GSM 7-bit default alphabet" },
847     { 0x01, "CBS DCS: Language indication at beginning of message" },
848     { 0x02, "CBS DCS: Language using the GSM 7-bit default alphabet" },
849     { 0x03, "CBS DCS: Reserved" },
850     { 0x04, "CBS DCS: General Data Coding indication - Uncompressed text, no message class" },
851     { 0x05, "CBS DCS: General Data Coding indication - Uncompressed text" },
852     { 0x06, "CBS DCS: General Data Coding indication - Compressed text, no message class" },
853     { 0x07, "CBS DCS: General Data Coding indication - Compressed text" },
854     { 0x08, "CBS DCS: Reserved" },
855     { 0x09, "CBS DCS: Message with User Data Header structure" },
856     { 0x0A, "CBS DCS: Reserved" },
857     { 0x0B, "CBS DCS: Reserved" },
858     { 0x0C, "CBS DCS: Reserved" },
859     { 0x0D, "CBS DCS: Reserved" },
860     { 0x0E, "CBS DCS: Defined by the WAP Forum" },
861     { 0x0F, "SMS DCS: Data coding / message class" },
862     { 0x00, NULL }
863 };
864
865 static const value_string vals_dcs_cbs_language[] = {
866     { 0x00, "German" },
867     { 0x01, "English" },
868     { 0x02, "Italian" },
869     { 0x03, "French" },
870     { 0x04, "Spanish" },
871     { 0x05, "Dutch" },
872     { 0x06, "Swedish" },
873     { 0x07, "Danish" },
874     { 0x08, "Portuguese" },
875     { 0x09, "Finnish" },
876     { 0x0A, "Norwegian" },
877     { 0x0B, "Greek" },
878     { 0x0C, "Turkish" },
879     { 0x0D, "Hungarian" },
880     { 0x0E, "Polish" },
881     { 0x0F, "Language not specified" },
882     { 0x10, "GSM 7-bit default alphabet - message preceded by language indication" },
883     { 0x11, "UCS-2 (16-bit) - message preceded by language indication" },
884     { 0x20, "Czech" },
885     { 0x21, "Hebrew" },
886     { 0x22, "Arabic" },
887     { 0x23, "Russian" },
888     { 0x24, "Icelandic" },
889     { 0x00, NULL }
890 };
891
892 static const value_string vals_dcs_cbs_class[] = {
893     { 0x00, "No message class" },
894     { 0x01, "Class 1 - User defined" },
895     { 0x02, "Class 2 - User defined" },
896     { 0x03, "Class 3 - TE specific" },
897     { 0x00, NULL }
898 };
899
900 static const value_string vals_dcs_wap_class[] = {
901     { 0x00, "No message class" },
902     { 0x01, "Class 1 - ME specific" },
903     { 0x02, "Class 2 - (U)SIM specific" },
904     { 0x03, "Class 3 - TE specific" },
905     { 0x00, NULL }
906 };
907
908 static const value_string vals_dcs_wap_charset[] = {
909     { 0x00, "Reserved" },
910     { 0x01, "8-bit data" },
911     { 0x02, "Reserved" },
912     { 0x03, "Reserved" },
913     { 0x00, NULL }
914 };
915
916 static const value_string vals_alert_on_message_delivery[] = {
917     { 0x00, "Use mobile default alert (Default)" },
918     { 0x01, "Use low-priority alert" },
919     { 0x02, "Use medium-priority alert" },
920     { 0x03, "Use high-priority alert" },
921     { 0x00, NULL }
922 };
923
924 static const range_string vals_congestion_state[] = {
925     {0,     0,      "Idle"},
926     {1,     29,     "Low Load"},
927     {30,    49,     "Medium Load"},
928     {50,    79,     "High Load"},
929     {80,    89,     "Optimum Load"}, /*Specs says 80-90, but that is probably a mistake */
930     {90,    99,     "Nearing Congestion"},
931     {100,   100,    "Congested / Maximum Load"},
932     { 0,    0,      NULL }
933 };
934
935 static const range_string vals_broadcast_channel_indicator[] = {
936     {0,     0,      "Basic Broadcast Channel (Default)"},
937     {1,     1,      "Extended Broadcast Channel"},
938     {2,     255,    "[Reserved]"},
939     { 0,    0,      NULL }
940 };
941
942 static const value_string vals_broadcast_message_class[] = {
943     {0, "No Class Specified (default)"},
944     {1, "Class 1 (User Defined)"},
945     {2, "Class 2 (User Defined)"},
946     {3, "Class 3 (Terminal Equipment)"},
947     {0, NULL }
948 };
949
950 static const range_string vals_broadcast_area_success[] = {
951     {0,     100,    "%"},
952     {101,   254,    "[Reserved]"},
953     {255,   255,    "Information not available"},
954     { 0,    0,      NULL }
955 };
956
957 static const value_string vals_broadcast_content_type_nw[] = {
958     {0,     "Generic"},
959     {1,     "GSM [23041]"},
960     {2,     "TDMA [IS824][ANSI-41]"},
961     {3,     "CDMA [IS824][IS637]"},
962     {0,     NULL }
963 };
964
965 static const value_string vals_broadcast_content_type_type[] = {
966     {0x0000,        "[System Service] Index"},
967     {0x0001,        "[System Service] Emergency Broadcasts"},
968     {0x0002,        "[System Service] IRDB Download"},
969     {0x0010,        "[News Service] News Flashes"},
970     {0x0011,        "[News Service] General News (Local)"},
971     {0x0012,        "[News Service] General News (Regional)"},
972     {0x0013,        "[News Service] General News (National)"},
973     {0x0014,        "[News Service] General News (Internationa)"},
974     {0x0015,        "[News Service] Business/Financial News (Local)"},
975     {0x0016,        "[News Service] Business/Financial News (Regional)"},
976     {0x0017,        "[News Service] Business/Financial News (National)"},
977     {0x0018,        "[News Service] Business/Financial News (International)"},
978     {0x0019,        "[News Service] Sports News (Local)"},
979     {0x001A,        "[News Service] Sports News (Regional)"},
980     {0x001B,        "[News Service] Sports News (National)"},
981     {0x001C,        "[News Service] Sports News (International)"},
982     {0x001D,        "[News Service] Entertainment News (Local)"},
983     {0x001E,        "[News Service] Entertainment News (Regional)"},
984     {0x001F,        "[News Service] Entertainment News (National)"},
985     {0x0020,        "[News Service] Entertainment News (International)"},
986     {0x0021,        "[Subscriber Information Services] Medical/Health/Hospitals"},
987     {0x0022,        "[Subscriber Information Services] Doctors"},
988     {0x0023,        "[Subscriber Information Services] Pharmacy"},
989     {0x0030,        "[Subscriber Information Services] Local Traffic/Road Reports"},
990     {0x0031,        "[Subscriber Information Services] Long Distance Traffic/Road Reports"},
991     {0x0032,        "[Subscriber Information Services] Taxis"},
992     {0x0033,        "[Subscriber Information Services] Weather"},
993     {0x0034,        "[Subscriber Information Services] Local Airport Flight Schedules"},
994     {0x0035,        "[Subscriber Information Services] Restaurants"},
995     {0x0036,        "[Subscriber Information Services] Lodgings"},
996     {0x0037,        "[Subscriber Information Services] Retail Directory"},
997     {0x0038,        "[Subscriber Information Services] Advertisements"},
998     {0x0039,        "[Subscriber Information Services] Stock Quotes"},
999     {0x0040,        "[Subscriber Information Services] Employment Opportunities"},
1000     {0x0041,        "[Subscriber Information Services] Technology News"},
1001     {0x0070,        "[Carrier Information Services] District (Base Station Info)"},
1002     {0x0071,        "[Carrier Information Services] Network Information"},
1003     {0x0080,        "[Subscriber Care Services] Operator Services"},
1004     {0x0081,        "[Subscriber Care Services] Directory Enquiries (National)"},
1005     {0x0082,        "[Subscriber Care Services] Directory Enquiries (International)"},
1006     {0x0083,        "[Subscriber Care Services] Customer Care (National)"},
1007     {0x0084,        "[Subscriber Care Services] Customer Care (International)"},
1008     {0x0085,        "[Subscriber Care Services] Local Date/Time/Time Zone"},
1009     {0x0100,        "[Multi Category Services] Multi Category Services"},
1010     {0x0000,        NULL }
1011 };
1012
1013 static const value_string vals_broadcast_frequency_interval_unit[] = {
1014     {0x00,  "As frequently as possible"},
1015     {0x08,  "seconds"},
1016     {0x09,  "minutes"},
1017     {0x0A,  "hours"},
1018     {0x0B,  "days"},
1019     {0x0C,  "weeks"},
1020     {0x0D,  "months"},
1021     {0x0E,  "years"},
1022     {0x00,  NULL }
1023 };
1024
1025 static const value_string vals_dest_addr_np_resolution[] = {
1026     {0x00,  "query has not been performed (default)"},
1027     {0x01,  "query has been performed, number not ported"},
1028     {0x02,  "query has been performed, number ported"},
1029     {0x00,  NULL }
1030 };
1031
1032 static const range_string vals_broadcast_area_identifier_format[] = {
1033     {0, 0, "Alias / Name"},
1034     {1, 1, "Ellipsoid Arc"},
1035     {2, 2, "Polygon"},
1036     {3, 255, "[Reserved]"},
1037     {0, 0,  NULL }
1038 };
1039
1040 /* Huawei SMPP+ extensions */
1041 static const value_string vals_mo_mt_flag[] = {
1042     { 0x01, "MO" },
1043     { 0x02, "MT" },
1044     { 0x03, "Reserved" },
1045     { 0x00, NULL }
1046 };
1047
1048 static const value_string vals_operation_result[] = {
1049     { 0x00, "Successful" },
1050     { 0x01, "Protocol is not supported" },
1051     { 0x0a, "Others" },
1052     { 0x0b, "MO account does not exist" },
1053     { 0x0c, "MT account does not exist" },
1054     { 0x0d, "MO account state is abnormal" },
1055     { 0x0e, "MT account state is abnormal" },
1056     { 0x0f, "MO account balance is not enough" },
1057     { 0x10, "MT account balance is not enough" },
1058     { 0x11, "MO VAS is not supported" },
1059     { 0x12, "MT VAS is not suppoeted" },
1060     { 0x13, "MO user is post-paid user and checked success" },
1061     { 0x14, "MT user is post-paid user and checked success" },
1062     { 0x15, "MO post-paid user status is incorrect" },
1063     { 0x16, "MT post-paid user status is incorrect" },
1064     { 0x17, "MO post-paid user account balance is not sufficient" },
1065     { 0x18, "MT post-paid user account balance is not sufficient" },
1066     { 0x19, "MO post-paid user value-added services are not supported" },
1067     { 0x1a, "MT post-paid user value-added services are not supported" },
1068     { 0x00, NULL }
1069 };
1070
1071 static const value_string vals_notify_mode[] = {
1072     { 0x01, "Deliver the report when it's successful or failed" },
1073     { 0x02, "Deliver the report only when it's failed" },
1074     { 0x03, "Deliver the report only when it's successful" },
1075     { 0x04, "Never deliver the report" },
1076     { 0x00, NULL }
1077 };
1078
1079 static const value_string vals_delivery_result[] = {
1080     { 0x00, "Successful" },
1081     { 0x01, "Unsuccessful" },
1082     { 0x00, NULL }
1083 };
1084
1085 static const value_string vals_msc_addr_noa    [] = {
1086     { 0x00, "Spare" },
1087     { 0x01, "Subscriber number" },
1088     { 0x02, "Unknown" },
1089     { 0x03, "National number" },
1090     { 0x04, "International" },
1091     { 0x00, NULL }
1092 };
1093
1094 static const value_string vals_msc_addr_npi    [] = {
1095     { 0x00, "Spare" },
1096     { 0x01, "ISDN (Telephony) numbering plan (Recommendation E.164)" },
1097     { 0x02, "Spare" },
1098     { 0x03, "Data numbering plan (Recommendation X.121) (national use)" },
1099     { 0x04, "Telex numbering plan (Recommendation F.69) (national use)" },
1100     { 0x05, "Reserved for national use" },
1101     { 0x06, "Reserved for national use" },
1102     { 0x07, "Spare" },
1103     { 0x00, NULL }
1104 };
1105
1106 static dissector_handle_t gsm_sms_handle;
1107
1108 /*
1109  * For Stats Tree
1110  */
1111 void
1112 smpp_stats_tree_init(stats_tree* st)
1113 {
1114     st_smpp_ops = stats_tree_create_node(st, "SMPP Operations", 0, TRUE);
1115     st_smpp_req = stats_tree_create_node(st, "SMPP Requests", st_smpp_ops, TRUE);
1116     st_smpp_res = stats_tree_create_node(st, "SMPP Responses", st_smpp_ops, TRUE);
1117     st_smpp_res_status = stats_tree_create_node(st, "SMPP Response Status", 0, TRUE);
1118
1119 }
1120
1121 int
1122 smpp_stats_tree_per_packet(stats_tree *st, /* st as it was passed to us */
1123                            packet_info *pinfo _U_,
1124                            epan_dissect_t *edt _U_,
1125                            const void *p) /* Used for getting SMPP command_id values */
1126 {
1127     smpp_tap_rec_t* tap_rec = (smpp_tap_rec_t*)p;
1128
1129     tick_stat_node(st, "SMPP Operations", 0, TRUE);
1130
1131     if ((tap_rec->command_id & 0x80000000) == 0x80000000) /* Response */
1132     {
1133         tick_stat_node(st, "SMPP Responses", st_smpp_ops, TRUE);
1134         tick_stat_node(st, val_to_str(tap_rec->command_id, vals_command_id, "Unknown 0x%08x"), st_smpp_res, FALSE);
1135
1136         tick_stat_node(st, "SMPP Response Status", 0, TRUE);
1137         tick_stat_node(st, val_to_str(tap_rec->command_status, vals_command_status, "Unknown 0x%08x"), st_smpp_res_status, FALSE);
1138
1139     }
1140     else  /* Request */
1141     {
1142         tick_stat_node(st, "SMPP Requests", st_smpp_ops, TRUE);
1143         tick_stat_node(st, val_to_str(tap_rec->command_id, vals_command_id, "Unknown 0x%08x"), st_smpp_req, FALSE);
1144     }
1145
1146     return 1;
1147 }
1148
1149 /*!
1150  * SMPP equivalent of mktime() (3). Convert date to standard 'time_t' format
1151  *
1152  * \param       datestr The SMPP-formatted date to convert
1153  * \param       secs    Returns the 'time_t' equivalent
1154  * \param       nsecs   Returns the additional nano-seconds
1155  *
1156  * \return              Whether time is specified relative or absolute
1157  * \retval      TRUE    Relative time
1158  * \retval      FALSE   Absolute time
1159  */
1160 static gboolean
1161 smpp_mktime(const char *datestr, time_t *secs, int *nsecs)
1162 {
1163     struct tm    r_time;
1164     time_t       t_diff;
1165     gboolean     relative = (datestr[15] == 'R') ? TRUE : FALSE;
1166
1167     r_time.tm_year = 10 * (datestr[0] - '0') + (datestr[1] - '0');
1168     /*
1169      * Y2K rollover date as recommended in appendix C
1170      */
1171     if (r_time.tm_year < 38)
1172         r_time.tm_year += 100;
1173     r_time.tm_mon  = 10 * (datestr[2] - '0') + (datestr[3] - '0');
1174     r_time.tm_mon--;
1175     r_time.tm_mday = 10 * (datestr[4] - '0') + (datestr[5] - '0');
1176     r_time.tm_hour = 10 * (datestr[6] - '0') + (datestr[7] - '0');
1177     r_time.tm_min  = 10 * (datestr[8] - '0') + (datestr[9] - '0');
1178     r_time.tm_sec  = 10 * (datestr[10] - '0') + (datestr[11] - '0');
1179     r_time.tm_isdst = -1;
1180
1181     if (relative == FALSE) {
1182         struct tm *gm, *local_time;
1183         int gm_hour, gm_min;
1184         time_t current_time;
1185
1186         *secs = mktime(&r_time);
1187
1188         /* Subtract out the timezone information since we will adjust for
1189          * the presented time's timezone below and then display in UTC.
1190          *
1191          * To do that, first determine the current timezone's offset to UTC.
1192          */
1193         current_time = time(NULL);
1194         gm = gmtime(&current_time);
1195         gm_hour = gm->tm_hour;
1196         gm_min = gm->tm_min;
1197         local_time = localtime(&current_time);
1198         /* Then subtract out that difference (whether the difference is
1199          * measured in hours, minutes, or both).
1200          */
1201         *secs -= 3600*(gm_hour - local_time->tm_hour);
1202         *secs -= 60*(gm_min - local_time->tm_min);
1203
1204         *nsecs = (datestr[12] - '0') * 100000000;
1205         t_diff = (10 * (datestr[13] - '0') + (datestr[14] - '0')) * 900;
1206         if (datestr[15] == '-')
1207             /* Represented time is behind UTC, shift it forward to UTC */
1208             *secs += t_diff;
1209         else if (datestr[15] == '+')
1210             /* Represented time is ahead of UTC, shift it backward to UTC */
1211             *secs -= t_diff;
1212     } else {
1213         *secs = r_time.tm_sec + 60 *
1214             (r_time.tm_min + 60 *
1215              (r_time.tm_hour + 24 *
1216               r_time.tm_mday));
1217         *nsecs = 0;
1218     }
1219
1220     return relative;
1221 }
1222
1223 /*!
1224  * Scanning routines to add standard types (byte, int, string...) to the
1225  * protocol tree.
1226  *
1227  * \param       tree    The protocol tree to add to
1228  * \param       tvb     Buffer containing the data
1229  * \param       field   Actual field whose value needs displaying
1230  * \param       offset  Location of field in buffer, returns location of
1231  *                      next field
1232  */
1233 static void
1234 smpp_handle_string(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
1235 {
1236     guint        len;
1237
1238     len = tvb_strsize(tvb, *offset);
1239     if (len > 1) {
1240         proto_tree_add_item(tree, field, tvb, *offset, len, ENC_NA);
1241     }
1242     (*offset) += len;
1243 }
1244
1245 /* NOTE - caller must free the returned string! */
1246 static char *
1247 smpp_handle_string_return(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
1248 {
1249     gint         len;
1250     char        *str;
1251
1252     len = tvb_strsize(tvb, *offset);
1253     if (len > 1) {
1254         str = (char *)tvb_get_ephemeral_stringz(tvb, *offset, &len);
1255         proto_tree_add_string(tree, field, tvb, *offset, len, str);
1256     } else {
1257         str = "";
1258     }
1259     (*offset) += len;
1260     return str;
1261 }
1262
1263 static void
1264 smpp_handle_string_z(proto_tree *tree, tvbuff_t *tvb, int field, int *offset,
1265                 const char *null_string)
1266 {
1267     gint         len;
1268
1269     len = tvb_strsize(tvb, *offset);
1270     if (len > 1) {
1271         proto_tree_add_item(tree, field, tvb, *offset, len, ENC_NA);
1272     } else {
1273         proto_tree_add_string(tree, field, tvb, *offset, len, null_string);
1274     }
1275     (*offset) += len;
1276 }
1277
1278 static void
1279 smpp_handle_int1(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
1280 {
1281     guint8       val;
1282
1283     val = tvb_get_guint8(tvb, *offset);
1284     proto_tree_add_uint(tree, field, tvb, *offset, 1, val);
1285     (*offset)++;
1286 }
1287
1288 static void
1289 smpp_handle_int2(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
1290 {
1291     guint        val;
1292
1293     val = tvb_get_ntohs(tvb, *offset);
1294     proto_tree_add_uint(tree, field, tvb, *offset, 2, val);
1295     (*offset) += 2;
1296 }
1297
1298 static void
1299 smpp_handle_int4(proto_tree *tree, tvbuff_t *tvb, int field, int *offset)
1300 {
1301     guint        val;
1302
1303     val = tvb_get_ntohl(tvb, *offset);
1304     proto_tree_add_uint(tree, field, tvb, *offset, 4, val);
1305     (*offset) += 4;
1306 }
1307
1308 static void
1309 smpp_handle_time(proto_tree *tree, tvbuff_t *tvb,
1310                  int field, int field_R, int *offset)
1311 {
1312     char         *strval;
1313     gint         len;
1314     nstime_t     tmptime;
1315
1316     strval = (char *) tvb_get_ephemeral_stringz(tvb, *offset, &len);
1317     if (*strval)
1318     {
1319         if (len >= 16)
1320         {
1321             if (smpp_mktime(strval, &tmptime.secs, &tmptime.nsecs))
1322                 proto_tree_add_time(tree, field_R, tvb, *offset, len, &tmptime);
1323             else
1324                 proto_tree_add_time(tree, field, tvb, *offset, len, &tmptime);
1325         }
1326         else
1327         {
1328             proto_tree_add_text(tree, tvb, *offset, len, "Invalid time: %s", strval);
1329         }
1330     }
1331     *offset += len;
1332 }
1333
1334 /*!
1335  * Scanning routine to handle the destination-list of 'submit_multi'
1336  *
1337  * \param       tree    The protocol tree to add to
1338  * \param       tvb     Buffer containing the data
1339  * \param       offset  Location of field in buffer, returns location of
1340  *                      next field
1341  */
1342 static void
1343 smpp_handle_dlist(proto_tree *tree, tvbuff_t *tvb, int *offset)
1344 {
1345     guint8       entries;
1346     int          tmpoff = *offset;
1347     proto_tree  *sub_tree = NULL;
1348     guint8       dest_flag;
1349
1350     if ((entries = tvb_get_guint8(tvb, tmpoff++))) {
1351         proto_item  *pi;
1352         pi = proto_tree_add_item(tree, hf_smpp_dlist, tvb, *offset, 1, ENC_NA);
1353         sub_tree = proto_item_add_subtree(pi, ett_dlist);
1354     }
1355     while (entries--)
1356     {
1357         dest_flag = tvb_get_guint8(tvb, tmpoff++);
1358         if (dest_flag == 1)                     /* SME address  */
1359         {
1360             smpp_handle_int1(sub_tree, tvb, hf_smpp_dest_addr_ton, &tmpoff);
1361             smpp_handle_int1(sub_tree, tvb, hf_smpp_dest_addr_npi, &tmpoff);
1362             smpp_handle_string(sub_tree,tvb,hf_smpp_destination_addr,&tmpoff);
1363         }
1364         else                                    /* Distribution list    */
1365         {
1366             smpp_handle_string(sub_tree, tvb, hf_smpp_dl_name, &tmpoff);
1367         }
1368     }
1369     *offset = tmpoff;
1370 }
1371
1372 /*!
1373  * Scanning routine to handle the destination result list
1374  * of 'submit_multi_resp'
1375  *
1376  * \param       tree    The protocol tree to add to
1377  * \param       tvb     Buffer containing the data
1378  * \param       offset  Location of field in buffer, returns location of
1379  *                      next field
1380  */
1381 static void
1382 smpp_handle_dlist_resp(proto_tree *tree, tvbuff_t *tvb, int *offset)
1383 {
1384     guint8       entries;
1385     int          tmpoff = *offset;
1386     proto_tree  *sub_tree = NULL;
1387
1388     if ((entries = tvb_get_guint8(tvb, tmpoff++))) {
1389         proto_item  *pi;
1390         pi = proto_tree_add_item(tree, hf_smpp_dlist_resp,
1391                                   tvb, *offset, 1, ENC_NA);
1392         sub_tree = proto_item_add_subtree(pi, ett_dlist_resp);
1393     }
1394     while (entries--)
1395     {
1396         smpp_handle_int1(sub_tree, tvb, hf_smpp_dest_addr_ton, &tmpoff);
1397         smpp_handle_int1(sub_tree, tvb, hf_smpp_dest_addr_npi, &tmpoff);
1398         smpp_handle_string(sub_tree,tvb,hf_smpp_destination_addr,&tmpoff);
1399         smpp_handle_int4(sub_tree, tvb, hf_smpp_error_status_code, &tmpoff);
1400     }
1401     *offset = tmpoff;
1402 }
1403
1404 /*!
1405  * Scanning routine to handle all optional parameters of SMPP-operations.
1406  * The parameters have the format Tag Length Value (TLV), with a 2-byte tag
1407  * and 2-byte length.
1408  *
1409  * \param       tree    The protocol tree to add to
1410  * \param       tvb     Buffer containing the data
1411  * \param       offset  Location of field in buffer, returns location of
1412  *                      next field
1413  */
1414 static void
1415 smpp_handle_tlv(proto_tree *tree, tvbuff_t *tvb, int *offset)
1416 {
1417     proto_tree *tlvs_tree = NULL;
1418     proto_item *pi;
1419
1420     if (tvb_reported_length_remaining(tvb, *offset) >= 1) {
1421         pi = proto_tree_add_item(tree, hf_smpp_opt_params,
1422                                  tvb, *offset, -1, ENC_NA);
1423         tlvs_tree = proto_item_add_subtree(pi, ett_opt_params);
1424     }
1425
1426     while (tvb_reported_length_remaining(tvb, *offset) >= 1)
1427     {
1428         proto_item *sub_tree;
1429         guint16  tag;
1430         guint16  length;
1431
1432         guint8   field;
1433         guint16  field16;
1434         guint8   major, minor;
1435         char     *strval=NULL;
1436
1437         tag = tvb_get_ntohs(tvb, *offset);
1438         length = tvb_get_ntohs(tvb, (*offset+2));
1439
1440         pi = proto_tree_add_none_format(tlvs_tree, hf_smpp_opt_param, tvb,
1441                                         *offset, length+4,
1442                                         "Optional parameter: %s (0x%04x)",
1443                                         val_to_str(tag, vals_tlv_tags, "0x%04x"), tag);
1444         sub_tree = proto_item_add_subtree(pi, ett_opt_param);
1445         proto_tree_add_uint(sub_tree,hf_smpp_opt_param_tag,tvb,*offset,2,tag);
1446         proto_tree_add_uint(sub_tree,hf_smpp_opt_param_len,tvb,*offset+2,2,length);
1447
1448         *offset += 4;
1449
1450         switch (tag) {
1451             case  0x0005:       /* dest_addr_subunit    */
1452                 smpp_handle_int1(sub_tree, tvb,
1453                                  hf_smpp_dest_addr_subunit, offset);
1454                 break;
1455             case  0x0006:       /* dest_network_type    */
1456                 smpp_handle_int1(sub_tree, tvb,
1457                                  hf_smpp_dest_network_type, offset);
1458                 break;
1459             case  0x0007:       /* dest_bearer_type     */
1460                 smpp_handle_int1(sub_tree, tvb,
1461                                  hf_smpp_dest_bearer_type, offset);
1462                 break;
1463             case  0x0008:       /* dest_telematics_id   */
1464                 smpp_handle_int2(sub_tree, tvb,
1465                                  hf_smpp_dest_telematics_id, offset);
1466                 break;
1467             case  0x000D:       /* source_addr_subunit  */
1468                 smpp_handle_int1(sub_tree, tvb,
1469                                  hf_smpp_source_addr_subunit, offset);
1470                 break;
1471             case  0x000E:       /* source_network_type  */
1472                 smpp_handle_int1(sub_tree, tvb,
1473                                  hf_smpp_source_network_type, offset);
1474                 break;
1475             case  0x000F:       /* source_bearer_type   */
1476                 smpp_handle_int1(sub_tree, tvb,
1477                                  hf_smpp_source_bearer_type, offset);
1478                 break;
1479             case  0x0010:       /* source_telematics_id */
1480                 smpp_handle_int2(sub_tree, tvb,
1481                                  hf_smpp_source_telematics_id, offset);
1482                 break;
1483             case  0x0017:       /* qos_time_to_live     */
1484                 smpp_handle_int4(sub_tree, tvb,
1485                                  hf_smpp_qos_time_to_live, offset);
1486                 break;
1487             case  0x0019:       /* payload_type */
1488                 smpp_handle_int1(sub_tree, tvb,
1489                                  hf_smpp_payload_type, offset);
1490                 break;
1491             case  0x001D:       /* additional_status_info_text  */
1492                 smpp_handle_string(sub_tree, tvb,
1493                                    hf_smpp_additional_status_info_text, offset);
1494                 break;
1495             case  0x001E:       /* receipted_message_id */
1496                 smpp_handle_string(sub_tree, tvb,
1497                                    hf_smpp_receipted_message_id, offset);
1498                 break;
1499             case  0x0030:       /* ms_msg_wait_facilities       */
1500                 field = tvb_get_guint8(tvb, *offset);
1501                 proto_tree_add_uint(sub_tree, hf_smpp_msg_wait_ind,
1502                                     tvb, *offset, 1, field);
1503                 proto_tree_add_uint(sub_tree, hf_smpp_msg_wait_type,
1504                                     tvb, *offset, 1, field);
1505                 (*offset)++;
1506                 break;
1507             case  0x0201:       /* privacy_indicator    */
1508                 smpp_handle_int1(sub_tree, tvb,
1509                                  hf_smpp_privacy_indicator, offset);
1510                 break;
1511             case  0x0202:       /* source_subaddress    */
1512                 if (length) {
1513                     proto_tree_add_item(sub_tree, hf_smpp_source_subaddress,
1514                                     tvb, *offset, length, ENC_NA);
1515                     (*offset) += length;
1516                 }
1517                 break;
1518             case  0x0203:       /* dest_subaddress      */
1519                 if (length) {
1520                     proto_tree_add_item(sub_tree, hf_smpp_dest_subaddress,
1521                                     tvb, *offset, length, ENC_NA);
1522                     (*offset) += length;
1523                 }
1524                 break;
1525             case  0x0204:       /* user_message_reference       */
1526                 smpp_handle_int2(sub_tree, tvb,
1527                                  hf_smpp_user_message_reference, offset);
1528                 break;
1529             case  0x0205:       /* user_response_code   */
1530                 smpp_handle_int1(sub_tree, tvb,
1531                                  hf_smpp_user_response_code, offset);
1532                 break;
1533             case  0x020A:       /* source_port  */
1534                 smpp_handle_int2(sub_tree, tvb,
1535                                  hf_smpp_source_port, offset);
1536                 break;
1537             case  0x020B:       /* destination_port     */
1538                 smpp_handle_int2(sub_tree, tvb,
1539                                  hf_smpp_destination_port, offset);
1540                 break;
1541             case  0x020C:       /* sar_msg_ref_num      */
1542                 smpp_handle_int2(sub_tree, tvb,
1543                                  hf_smpp_sar_msg_ref_num, offset);
1544                 break;
1545             case  0x020D:       /* language_indicator   */
1546                 smpp_handle_int1(sub_tree, tvb,
1547                                  hf_smpp_language_indicator, offset);
1548                 break;
1549             case  0x020E:       /* sar_total_segments   */
1550                 smpp_handle_int1(sub_tree, tvb,
1551                                  hf_smpp_sar_total_segments, offset);
1552                 break;
1553             case  0x020F:       /* sar_segment_seqnum   */
1554                 smpp_handle_int1(sub_tree, tvb,
1555                                  hf_smpp_sar_segment_seqnum, offset);
1556                 break;
1557             case  0x0210:       /* SC_interface_version */
1558                 field = tvb_get_guint8(tvb, *offset);
1559                 minor = field & 0x0F;
1560                 major = (field & 0xF0) >> 4;
1561                 strval=ep_strdup_printf("%u.%u", major, minor);
1562                 proto_tree_add_string(sub_tree, hf_smpp_SC_interface_version,
1563                                       tvb, *offset, 1, strval);
1564                 (*offset)++;
1565                 break;
1566             case  0x0302:       /* callback_num_pres_ind        */
1567                 field = tvb_get_guint8(tvb, *offset);
1568                 proto_tree_add_uint(sub_tree, hf_smpp_callback_num_pres,
1569                                     tvb, *offset, 1, field);
1570                 proto_tree_add_uint(sub_tree, hf_smpp_callback_num_scrn,
1571                                     tvb, *offset, 1, field);
1572                 (*offset)++;
1573                 break;
1574             case  0x0303:       /* callback_num_atag    */
1575                 if (length)
1576                     proto_tree_add_item(sub_tree, hf_smpp_callback_num_atag,
1577                                         tvb, *offset, length, ENC_NA);
1578                 (*offset) += length;
1579                 break;
1580             case  0x0304:       /* number_of_messages   */
1581                 smpp_handle_int1(sub_tree, tvb,
1582                                  hf_smpp_number_of_messages, offset);
1583                 break;
1584             case  0x0381:       /* callback_num */
1585                 if (length)
1586                     proto_tree_add_item(sub_tree, hf_smpp_callback_num,
1587                                         tvb, *offset, length, ENC_NA);
1588                 (*offset) += length;
1589                 break;
1590             case  0x0420:       /* dpf_result   */
1591                 smpp_handle_int1(sub_tree, tvb,
1592                                  hf_smpp_dpf_result, offset);
1593                 break;
1594             case  0x0421:       /* set_dpf      */
1595                 smpp_handle_int1(sub_tree, tvb,
1596                                  hf_smpp_set_dpf, offset);
1597                 break;
1598             case  0x0422:       /* ms_availability_status       */
1599                 smpp_handle_int1(sub_tree, tvb,
1600                                  hf_smpp_ms_availability_status, offset);
1601                 break;
1602             case  0x0423:       /* network_error_code   */
1603                 smpp_handle_int1(sub_tree, tvb,
1604                                  hf_smpp_network_error_type, offset);
1605                 smpp_handle_int2(sub_tree, tvb,
1606                                  hf_smpp_network_error_code, offset);
1607                 break;
1608             case  0x0424:       /* message_payload      */
1609                 if (length)
1610                     proto_tree_add_item(sub_tree, hf_smpp_message_payload,
1611                                         tvb, *offset, length, ENC_NA);
1612                 (*offset) += length;
1613                 break;
1614             case  0x0425:       /* delivery_failure_reason      */
1615                 smpp_handle_int1(sub_tree, tvb,
1616                                  hf_smpp_delivery_failure_reason, offset);
1617                 break;
1618             case  0x0426:       /* more_messages_to_send        */
1619                 smpp_handle_int1(sub_tree, tvb,
1620                                  hf_smpp_more_messages_to_send, offset);
1621                 break;
1622             case  0x0427:       /* message_state        */
1623                 smpp_handle_int1(sub_tree, tvb,
1624                                  hf_smpp_message_state, offset);
1625                 break;
1626             case        0x0428: /* congestion_state */
1627                 smpp_handle_int1(sub_tree, tvb,
1628                                  hf_smpp_congestion_state, offset);
1629
1630                 break;
1631             case  0x0501:       /* ussd_service_op      */
1632                 smpp_handle_int1(sub_tree, tvb,
1633                                  hf_smpp_ussd_service_op, offset);
1634                 break;
1635             case 0x0600:        /* broadcast_channel_indicator */
1636                 smpp_handle_int1(sub_tree, tvb,
1637                                  hf_smpp_broadcast_channel_indicator, offset);
1638                 break;
1639             case 0x0601:        /* broadcast_content_type */
1640                 field = tvb_get_guint8(tvb, *offset);
1641                 proto_tree_add_uint(sub_tree, hf_smpp_broadcast_content_type_nw, tvb, *offset, 1, field);
1642                 (*offset)++;
1643                 field16 = tvb_get_ntohs(tvb, *offset);
1644                 proto_tree_add_uint(sub_tree, hf_smpp_broadcast_content_type_type, tvb, *offset, 2, field16);
1645                 (*offset) += 2;
1646                 break;
1647             case 0x0602:        /* broadcast_content_type_info */
1648                 if (length)
1649                     proto_tree_add_item(sub_tree, hf_smpp_broadcast_content_type_info,
1650                                         tvb, *offset, length, ENC_NA);
1651                 (*offset) += length;
1652                 break;
1653             case 0x0603:        /* broadcast_message_class */
1654                 smpp_handle_int1(sub_tree, tvb,
1655                                 hf_smpp_broadcast_message_class, offset);
1656                 break;
1657             case 0x0604:        /* broadcast_rep_num */
1658                 smpp_handle_int1(sub_tree, tvb,
1659                                 hf_smpp_broadcast_rep_num, offset);
1660                 break;
1661             case 0x0605:        /* broadcast_frequency_interval */
1662                 field = tvb_get_guint8(tvb, *offset);
1663                 proto_tree_add_uint(sub_tree, hf_smpp_broadcast_frequency_interval_unit, tvb, *offset, 1, field);
1664                 (*offset)++;
1665                 field16 = tvb_get_ntohs(tvb, *offset);
1666                 proto_tree_add_uint(sub_tree, hf_smpp_broadcast_frequency_interval_value, tvb, *offset, 2, field16);
1667                 (*offset) += 2;
1668                 break;
1669             case 0x0606:        /* broadcast_area_identifier */
1670                 field = tvb_get_guint8(tvb, *offset);
1671                 proto_tree_add_uint(sub_tree, hf_smpp_broadcast_area_identifier_format, tvb, *offset, 1, field);
1672                 proto_tree_add_item(sub_tree, hf_smpp_broadcast_area_identifier,
1673                                         tvb, *offset, length, ENC_NA);
1674                 (*offset) += length;
1675                 break;
1676             case 0x0607:        /* broadcast_error_status */
1677                 smpp_handle_int4(sub_tree, tvb,
1678                                 hf_smpp_broadcast_error_status, offset);
1679                 break;
1680             case 0x0608:        /* broadcast_area_success */
1681                 smpp_handle_int1(sub_tree, tvb,
1682                                 hf_smpp_broadcast_area_success, offset);
1683                 break;
1684             case 0x0609:        /* broadcast_end_time */
1685                 smpp_handle_time(sub_tree, tvb, hf_smpp_broadcast_end_time,
1686                                 hf_smpp_broadcast_end_time_r, offset);
1687                 break;
1688             case 0x060A:        /* broadcast_service_group */
1689                 if (length)
1690                     proto_tree_add_item(sub_tree, hf_smpp_broadcast_service_group,
1691                                         tvb, *offset, length, ENC_NA);
1692                 (*offset) += length;
1693                 break;
1694             case 0x060B:        /* billing_identification */
1695                 if (length)
1696                     proto_tree_add_item(sub_tree, hf_smpp_billing_identification,
1697                                         tvb, *offset, length, ENC_NA);
1698                 (*offset) += length;
1699                 break;
1700             /* 0x060C is skipped in the specs for some reason :-? */
1701             case 0x060D:        /* source_network_id */
1702                 smpp_handle_string_z(sub_tree, tvb, hf_smpp_source_network_id,
1703                                 offset, "Empty!");
1704                 break;
1705             case 0x060E:        /* dest_network_id */
1706                 smpp_handle_string_z(sub_tree, tvb, hf_smpp_dest_network_id,
1707                                 offset, "Empty!");
1708                 break;
1709             case 0x060F:        /* source_node_id */
1710                 if (length)
1711                     proto_tree_add_item(sub_tree, hf_smpp_source_node_id,
1712                                         tvb, *offset, length, ENC_NA);
1713                 (*offset) += length;
1714                 break;
1715             case 0x0610:        /* dest_node_id */
1716                 if (length)
1717                     proto_tree_add_item(sub_tree, hf_smpp_dest_node_id,
1718                                         tvb, *offset, length, ENC_NA);
1719                 (*offset) += length;
1720                 break;
1721             case 0x0611:        /* dest_addr_np_resolution */
1722                 smpp_handle_int1(sub_tree, tvb,
1723                                 hf_smpp_dest_addr_np_resolution, offset);
1724                 break;
1725             case 0x0612:        /* dest_addr_np_information */
1726                 if (length)
1727                     proto_tree_add_item(sub_tree, hf_smpp_dest_addr_np_information,
1728                                         tvb, *offset, length, ENC_NA);
1729                 (*offset) += length;
1730                 break;
1731             case 0x0613:        /* dest_addr_np_country */
1732                 /* TODO : Fetch values from packet-e164? */
1733                 if (length)
1734                     proto_tree_add_item(sub_tree, hf_smpp_dest_addr_np_country,
1735                                         tvb, *offset, length, ENC_NA);
1736                 (*offset) += length;
1737                 break;
1738             case  0x1201:       /* display_time */
1739                 smpp_handle_int1(sub_tree, tvb,
1740                                  hf_smpp_display_time, offset);
1741                 break;
1742             case  0x1203:       /* sms_signal   */
1743                 smpp_handle_int2(sub_tree, tvb,
1744                                  hf_smpp_sms_signal, offset);
1745                 /*! \todo Fill as per TIA/EIA-136-710-A         */
1746                 break;
1747             case  0x1204:       /* ms_validity  */
1748                 smpp_handle_int1(sub_tree, tvb,
1749                                  hf_smpp_ms_validity, offset);
1750                 break;
1751             case  0x130C:       /* alert_on_message_delivery    */
1752                 if (length == 0) {
1753                         proto_tree_add_item(sub_tree,
1754                                     hf_smpp_alert_on_message_delivery_null,
1755                                     tvb, *offset, length, ENC_NA);
1756                 } else {
1757                         smpp_handle_int1(sub_tree, tvb,
1758                                     hf_smpp_alert_on_message_delivery, offset);
1759                 }
1760                 break;
1761             case  0x1380:       /* its_reply_type       */
1762                 smpp_handle_int1(sub_tree, tvb,
1763                                  hf_smpp_its_reply_type, offset);
1764                 break;
1765             case  0x1383:       /* its_session_info     */
1766                 smpp_handle_int1(sub_tree, tvb,
1767                                  hf_smpp_its_session_number, offset);
1768                 field = tvb_get_guint8(tvb, *offset);
1769                 proto_tree_add_uint(sub_tree, hf_smpp_its_session_sequence,
1770                                     tvb, *offset, 1, field);
1771                 proto_tree_add_uint(sub_tree, hf_smpp_its_session_ind,
1772                                     tvb, *offset, 1, field);
1773                 (*offset)++;
1774                 break;
1775
1776             default:
1777                 /* TODO : Hopefully to be implemented soon - handle vendor specific TLVs
1778                  * from a dictionary before treating them as unknown! */
1779                 if ((tag >= 0x1400) && (tag <= 0x3FFF)) {
1780                     proto_tree_add_item(sub_tree, hf_smpp_vendor_op, tvb,
1781                                         *offset, length, ENC_NA);
1782                 } else {
1783                     proto_tree_add_item(sub_tree, hf_smpp_reserved_op, tvb,
1784                                         *offset, length, ENC_NA);
1785                 }
1786
1787                 proto_item_append_text(sub_tree,": %s", tvb_bytes_to_str(tvb,*offset,length));
1788                 (*offset) += length;
1789                 break;
1790         }
1791     }
1792 }
1793
1794 void
1795 smpp_handle_dcs(proto_tree *tree, tvbuff_t *tvb, int *offset)
1796 {
1797     guint8       val;
1798     int off = *offset;
1799     proto_tree *subtree = NULL;
1800     proto_item *pi;
1801
1802     val = tvb_get_guint8(tvb, off);
1803     pi = proto_tree_add_uint(tree, hf_smpp_data_coding, tvb, off, 1, val);
1804     subtree = proto_item_add_subtree(pi, ett_dcs);
1805     /* SMPP Data Coding Scheme */
1806     proto_tree_add_uint(subtree, hf_smpp_dcs, tvb, off, 1, val);
1807     /* GSM SMS Data Coding Scheme */
1808     proto_tree_add_text(subtree, tvb, off, 1,
1809                         "GSM SMS Data Coding");
1810     proto_tree_add_uint(subtree,
1811                         hf_smpp_dcs_sms_coding_group, tvb, off, 1, val);
1812     if (val>>6 == 2) { /* Reserved */
1813         ;
1814     } else if (val < 0xF0) {
1815         proto_tree_add_boolean(subtree,
1816                                hf_smpp_dcs_text_compression, tvb, off, 1, val);
1817         proto_tree_add_boolean(subtree,
1818                                hf_smpp_dcs_class_present, tvb, off, 1, val);
1819         proto_tree_add_uint(subtree,
1820                             hf_smpp_dcs_charset, tvb, off, 1, val);
1821         if (val & 0x10)
1822             proto_tree_add_uint(subtree,
1823                                 hf_smpp_dcs_class, tvb, off, 1, val);
1824     } else {
1825         if (val & 0x08)
1826             proto_tree_add_text(subtree, tvb, off, 1,
1827                                 "SMPP: Bit .... 1... should be 0 (reserved)");
1828         proto_tree_add_uint(subtree,
1829                             hf_smpp_dcs_charset, tvb, off, 1, val);
1830         proto_tree_add_uint(subtree,
1831                             hf_smpp_dcs_class, tvb, off, 1, val);
1832     }
1833     /* Cell Broadcast Service (CBS) Data Coding Scheme */
1834     proto_tree_add_text(subtree, tvb, off, 1,
1835                         "GSM CBS Data Coding");
1836     proto_tree_add_uint(subtree,
1837                         hf_smpp_dcs_cbs_coding_group, tvb, off, 1, val);
1838     if (val < 0x40) { /* Language specified */
1839         proto_tree_add_uint(subtree,
1840                             hf_smpp_dcs_cbs_language, tvb, off, 1, val);
1841     } else if (val>>6 == 1) { /* General Data Coding indication */
1842         proto_tree_add_boolean(subtree,
1843                                hf_smpp_dcs_text_compression, tvb, off, 1, val);
1844         proto_tree_add_boolean(subtree,
1845                                hf_smpp_dcs_class_present, tvb, off, 1, val);
1846         proto_tree_add_uint(subtree,
1847                             hf_smpp_dcs_charset, tvb, off, 1, val);
1848         if (val & 0x10)
1849             proto_tree_add_uint(subtree,
1850                                 hf_smpp_dcs_class, tvb, off, 1, val);
1851     } else if (val>>6 == 2) { /* Message with UDH structure */
1852         proto_tree_add_uint(subtree,
1853                             hf_smpp_dcs_charset, tvb, off, 1, val);
1854         proto_tree_add_uint(subtree,
1855                             hf_smpp_dcs_class, tvb, off, 1, val);
1856     } else if (val>>4 == 14) { /* WAP Forum */
1857         proto_tree_add_uint(subtree,
1858                             hf_smpp_dcs_wap_charset, tvb, off, 1, val);
1859         proto_tree_add_uint(subtree,
1860                             hf_smpp_dcs_wap_class, tvb, off, 1, val);
1861     } else if (val>>4 == 15) { /* Data coding / message handling */
1862         if (val & 0x08)
1863             proto_tree_add_text(subtree, tvb, off, 1,
1864                                 "SMPP: Bit .... 1... should be 0 (reserved)");
1865         proto_tree_add_uint(subtree,
1866                             hf_smpp_dcs_charset, tvb, off, 1, val);
1867         proto_tree_add_uint(subtree,
1868                             hf_smpp_dcs_cbs_class, tvb, off, 1, val);
1869     }
1870
1871     (*offset)++;
1872 }
1873
1874 /*!
1875  * The next set of routines handle the different operations, associated
1876  * with SMPP.
1877  */
1878 static void
1879 bind_receiver(proto_tree *tree, tvbuff_t *tvb)
1880 {
1881     int          offset = 0;
1882     guint8       field;
1883     guint8       major, minor;
1884     char         *strval;
1885
1886     smpp_handle_string(tree, tvb, hf_smpp_system_id, &offset);
1887     smpp_handle_string(tree, tvb, hf_smpp_password, &offset);
1888     smpp_handle_string(tree, tvb, hf_smpp_system_type, &offset);
1889     field = tvb_get_guint8(tvb, offset++);
1890     minor = field & 0x0F;
1891     major = (field & 0xF0) >> 4;
1892     strval=ep_strdup_printf("%u.%u", major, minor);
1893     proto_tree_add_string(tree, hf_smpp_interface_version, tvb,
1894                           offset - 1, 1, strval);
1895     smpp_handle_int1(tree, tvb, hf_smpp_addr_ton, &offset);
1896     smpp_handle_int1(tree, tvb, hf_smpp_addr_npi, &offset);
1897     smpp_handle_string(tree, tvb, hf_smpp_address_range, &offset);
1898 }
1899
1900 #define bind_transmitter(a, b) bind_receiver(a, b)
1901
1902 static void
1903 query_sm(proto_tree *tree, tvbuff_t *tvb)
1904 {
1905     int          offset = 0;
1906
1907     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
1908     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1909     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1910     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
1911 }
1912
1913 #define bind_transceiver(a, b) bind_receiver(a, b)
1914
1915 static void
1916 outbind(proto_tree *tree, tvbuff_t *tvb)
1917 {
1918     int          offset = 0;
1919
1920     smpp_handle_string(tree, tvb, hf_smpp_system_id, &offset);
1921     smpp_handle_string(tree, tvb, hf_smpp_password, &offset);
1922 }
1923
1924 static void
1925 submit_sm(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
1926                 proto_tree *top_tree)
1927 {
1928     tvbuff_t    *tvb_msg;
1929     int          offset = 0;
1930     guint8       flag, udhi;
1931     guint8       length;
1932     char *src_str = NULL;
1933     char *dst_str = NULL;
1934     address save_src, save_dst;
1935
1936     smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
1937     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
1938     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
1939     src_str = smpp_handle_string_return(tree, tvb, hf_smpp_source_addr, &offset);
1940     smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_ton, &offset);
1941     smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_npi, &offset);
1942     dst_str = smpp_handle_string_return(tree, tvb, hf_smpp_destination_addr, &offset);
1943     flag = tvb_get_guint8(tvb, offset);
1944     udhi = flag & 0x40;
1945     proto_tree_add_uint(tree, hf_smpp_esm_submit_msg_mode,
1946                         tvb, offset, 1, flag);
1947     proto_tree_add_uint(tree, hf_smpp_esm_submit_msg_type,
1948                         tvb, offset, 1, flag);
1949     proto_tree_add_uint(tree, hf_smpp_esm_submit_features,
1950                         tvb, offset, 1, flag);
1951     offset++;
1952     smpp_handle_int1(tree, tvb, hf_smpp_protocol_id, &offset);
1953     smpp_handle_int1(tree, tvb, hf_smpp_priority_flag, &offset);
1954     if (tvb_get_guint8(tvb,offset)) {
1955         smpp_handle_time(tree, tvb, hf_smpp_schedule_delivery_time,
1956                          hf_smpp_schedule_delivery_time_r, &offset);
1957     } else { /* Time = NULL means Immediate delivery */
1958         proto_tree_add_text(tree, tvb, offset++, 1,
1959                             "Scheduled delivery time: Immediate delivery");
1960     }
1961     if (tvb_get_guint8(tvb,offset)) {
1962         smpp_handle_time(tree, tvb, hf_smpp_validity_period,
1963                          hf_smpp_validity_period_r, &offset);
1964     } else { /* Time = NULL means SMSC default validity */
1965         proto_tree_add_text(tree, tvb, offset++, 1,
1966                             "Validity period: SMSC default validity period");
1967     }
1968     flag = tvb_get_guint8(tvb, offset);
1969     proto_tree_add_uint(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
1970     proto_tree_add_uint(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
1971     proto_tree_add_uint(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
1972     offset++;
1973     smpp_handle_int1(tree, tvb, hf_smpp_replace_if_present_flag, &offset);
1974         smpp_handle_dcs(tree, tvb, &offset);
1975     smpp_handle_int1(tree, tvb, hf_smpp_sm_default_msg_id, &offset);
1976     length = tvb_get_guint8(tvb, offset);
1977     proto_tree_add_uint(tree, hf_smpp_sm_length, tvb, offset++, 1, length);
1978     if (length)
1979     {
1980         proto_tree_add_item(tree, hf_smpp_short_message,
1981                             tvb, offset, length, ENC_NA);
1982         if (udhi) /* UDHI indicator present */
1983         {
1984             DebugLog(("UDHI present - set addresses\n"));
1985             /* Save original addresses */
1986             SET_ADDRESS(&save_src, pinfo->src.type, pinfo->src.len, pinfo->src.data);
1987             SET_ADDRESS(&save_dst, pinfo->dst.type, pinfo->dst.len, pinfo->dst.data);
1988             /* Set SMPP source and destination address */
1989             SET_ADDRESS(&(pinfo->src), AT_STRINGZ, 1+(int)strlen(src_str), src_str);
1990             SET_ADDRESS(&(pinfo->dst), AT_STRINGZ, 1+(int)strlen(dst_str), dst_str);
1991             tvb_msg = tvb_new_subset (tvb, offset,
1992                     MIN(length, tvb_reported_length(tvb) - offset), length);
1993             call_dissector (gsm_sms_handle, tvb_msg, pinfo, top_tree);
1994             /* Restore original addresses */
1995             SET_ADDRESS(&(pinfo->src), save_src.type, save_src.len, save_src.data );
1996             SET_ADDRESS(&(pinfo->dst), save_dst.type, save_dst.len, save_dst.data);
1997         }
1998         offset += length;
1999     }
2000     /* Get rid of SMPP text string addresses */
2001     smpp_handle_tlv(tree, tvb, &offset);
2002 }
2003
2004 #define deliver_sm(a, b, c, d) submit_sm(a, b, c, d)
2005
2006 static void
2007 replace_sm(proto_tree *tree, tvbuff_t *tvb)
2008 {
2009     int          offset = 0;
2010     guint8       flag;
2011     guint8       length;
2012
2013     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
2014     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
2015     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
2016     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
2017         if (tvb_get_guint8(tvb,offset)) {
2018     smpp_handle_time(tree, tvb, hf_smpp_schedule_delivery_time,
2019                                 hf_smpp_schedule_delivery_time_r, &offset);
2020         } else { /* Time = NULL */
2021                 proto_tree_add_text(tree, tvb, offset++, 1,
2022                                 "Scheduled delivery time: Keep initial delivery time setting");
2023         }
2024         if (tvb_get_guint8(tvb,offset)) {
2025     smpp_handle_time(tree, tvb, hf_smpp_validity_period,
2026                                 hf_smpp_validity_period_r, &offset);
2027         } else { /* Time = NULL */
2028                 proto_tree_add_text(tree, tvb, offset++, 1,
2029                                 "Validity period: Keep initial validity period setting");
2030         }
2031     flag = tvb_get_guint8(tvb, offset);
2032     proto_tree_add_uint(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
2033     proto_tree_add_uint(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
2034     proto_tree_add_uint(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
2035     offset++;
2036     smpp_handle_int1(tree, tvb, hf_smpp_sm_default_msg_id, &offset);
2037     length = tvb_get_guint8(tvb, offset);
2038     proto_tree_add_uint(tree, hf_smpp_sm_length, tvb, offset++, 1, length);
2039     if (length)
2040         proto_tree_add_item(tree, hf_smpp_short_message,
2041                             tvb, offset, length, ENC_NA);
2042     offset += length;
2043 }
2044
2045 static void
2046 cancel_sm(proto_tree *tree, tvbuff_t *tvb)
2047 {
2048     int          offset = 0;
2049
2050     smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
2051     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
2052     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
2053     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
2054     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
2055     smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_ton, &offset);
2056     smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_npi, &offset);
2057     smpp_handle_string(tree, tvb, hf_smpp_destination_addr, &offset);
2058 }
2059
2060 static void
2061 submit_multi(proto_tree *tree, tvbuff_t *tvb)
2062 {
2063     int          offset = 0;
2064     guint8       flag;
2065     guint8       length;
2066
2067     smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
2068     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
2069     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
2070     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
2071
2072     smpp_handle_dlist(tree, tvb, &offset);
2073
2074     flag = tvb_get_guint8(tvb, offset);
2075     proto_tree_add_uint(tree, hf_smpp_esm_submit_msg_mode,
2076             tvb, offset, 1, flag);
2077     proto_tree_add_uint(tree, hf_smpp_esm_submit_msg_type,
2078             tvb, offset, 1, flag);
2079     proto_tree_add_uint(tree, hf_smpp_esm_submit_features,
2080             tvb, offset, 1, flag);
2081     offset++;
2082     smpp_handle_int1(tree, tvb, hf_smpp_protocol_id, &offset);
2083     smpp_handle_int1(tree, tvb, hf_smpp_priority_flag, &offset);
2084     if (tvb_get_guint8(tvb,offset)) {
2085         smpp_handle_time(tree, tvb, hf_smpp_schedule_delivery_time,
2086                 hf_smpp_schedule_delivery_time_r, &offset);
2087     } else { /* Time = NULL means Immediate delivery */
2088         proto_tree_add_text(tree, tvb, offset++, 1,
2089                 "Scheduled delivery time: Immediate delivery");
2090     }
2091     if (tvb_get_guint8(tvb,offset)) {
2092         smpp_handle_time(tree, tvb, hf_smpp_validity_period,
2093                 hf_smpp_validity_period_r, &offset);
2094     } else { /* Time = NULL means SMSC default validity */
2095         proto_tree_add_text(tree, tvb, offset++, 1,
2096                 "Validity period: SMSC default validity period");
2097     }
2098     flag = tvb_get_guint8(tvb, offset);
2099     proto_tree_add_uint(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
2100     proto_tree_add_uint(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
2101     proto_tree_add_uint(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
2102     offset++;
2103     smpp_handle_int1(tree, tvb, hf_smpp_replace_if_present_flag, &offset);
2104     smpp_handle_dcs(tree, tvb, &offset);
2105     smpp_handle_int1(tree, tvb, hf_smpp_sm_default_msg_id, &offset);
2106     length = tvb_get_guint8(tvb, offset);
2107     proto_tree_add_uint(tree, hf_smpp_sm_length, tvb, offset++, 1, length);
2108     if (length)
2109         proto_tree_add_item(tree, hf_smpp_short_message,
2110                 tvb, offset, length, ENC_NA);
2111     offset += length;
2112     smpp_handle_tlv(tree, tvb, &offset);
2113 }
2114
2115 static void
2116 alert_notification(proto_tree *tree, tvbuff_t *tvb)
2117 {
2118     int          offset = 0;
2119
2120     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
2121     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
2122     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
2123     smpp_handle_int1(tree, tvb, hf_smpp_esme_addr_ton, &offset);
2124     smpp_handle_int1(tree, tvb, hf_smpp_esme_addr_npi, &offset);
2125     smpp_handle_string(tree, tvb, hf_smpp_esme_addr, &offset);
2126     smpp_handle_tlv(tree, tvb, &offset);
2127 }
2128
2129 static void
2130 data_sm(proto_tree *tree, tvbuff_t *tvb)
2131 {
2132     int          offset = 0;
2133     guint8       flag;
2134
2135     smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
2136     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
2137     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
2138     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
2139     smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_ton, &offset);
2140     smpp_handle_int1(tree, tvb, hf_smpp_dest_addr_npi, &offset);
2141     smpp_handle_string(tree, tvb, hf_smpp_destination_addr, &offset);
2142     flag = tvb_get_guint8(tvb, offset);
2143     proto_tree_add_uint(tree, hf_smpp_esm_submit_msg_mode,
2144                         tvb, offset, 1, flag);
2145     proto_tree_add_uint(tree, hf_smpp_esm_submit_msg_type,
2146                         tvb, offset, 1, flag);
2147     proto_tree_add_uint(tree, hf_smpp_esm_submit_features,
2148                         tvb, offset, 1, flag);
2149     offset++;
2150     flag = tvb_get_guint8(tvb, offset);
2151     proto_tree_add_uint(tree, hf_smpp_regdel_receipt, tvb, offset, 1, flag);
2152     proto_tree_add_uint(tree, hf_smpp_regdel_acks, tvb, offset, 1, flag);
2153     proto_tree_add_uint(tree, hf_smpp_regdel_notif, tvb, offset, 1, flag);
2154     offset++;
2155         smpp_handle_dcs(tree, tvb, &offset);
2156     smpp_handle_tlv(tree, tvb, &offset);
2157 }
2158
2159 /*
2160  * Request operations introduced in the SMPP 5.0
2161  */
2162 static void
2163 broadcast_sm(proto_tree *tree, tvbuff_t *tvb)
2164 {
2165     int          offset = 0;
2166
2167     smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
2168     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
2169     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
2170     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
2171     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
2172     smpp_handle_int1(tree, tvb, hf_smpp_priority_flag, &offset);
2173     if (tvb_get_guint8(tvb,offset)) {
2174         smpp_handle_time(tree, tvb, hf_smpp_schedule_delivery_time,
2175                 hf_smpp_schedule_delivery_time_r, &offset);
2176     } else { /* Time = NULL means Immediate delivery */
2177         proto_tree_add_text(tree, tvb, offset++, 1,
2178                 "Scheduled delivery time: Immediate delivery");
2179     }
2180     if (tvb_get_guint8(tvb,offset)) {
2181         smpp_handle_time(tree, tvb, hf_smpp_validity_period,
2182                 hf_smpp_validity_period_r, &offset);
2183     } else { /* Time = NULL means SMSC default validity */
2184         proto_tree_add_text(tree, tvb, offset++, 1,
2185                 "Validity period: SMSC default validity period");
2186     }
2187     smpp_handle_int1(tree, tvb, hf_smpp_replace_if_present_flag, &offset);
2188     smpp_handle_dcs(tree, tvb, &offset);
2189     smpp_handle_int1(tree, tvb, hf_smpp_sm_default_msg_id, &offset);
2190     smpp_handle_tlv(tree, tvb, &offset);
2191 }
2192
2193 static void
2194 query_broadcast_sm(proto_tree *tree, tvbuff_t *tvb)
2195 {
2196     int          offset = 0;
2197
2198     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
2199     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
2200     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
2201     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
2202     smpp_handle_tlv(tree, tvb, &offset);
2203 }
2204
2205 static void
2206 cancel_broadcast_sm(proto_tree *tree, tvbuff_t *tvb)
2207 {
2208     int          offset = 0;
2209
2210     smpp_handle_string_z(tree, tvb, hf_smpp_service_type, &offset, "(Default)");
2211     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
2212     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_ton, &offset);
2213     smpp_handle_int1(tree, tvb, hf_smpp_source_addr_npi, &offset);
2214     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
2215     smpp_handle_tlv(tree, tvb, &offset);
2216 }
2217
2218 /*!
2219  * The next set of routines handle the different operation-responses,
2220  * associated with SMPP.
2221  */
2222 static void
2223 bind_receiver_resp(proto_tree *tree, tvbuff_t *tvb)
2224 {
2225     int          offset = 0;
2226
2227     smpp_handle_string(tree, tvb, hf_smpp_system_id, &offset);
2228     smpp_handle_tlv(tree, tvb, &offset);
2229 }
2230
2231 #define bind_transmitter_resp(a, b) bind_receiver_resp(a, b)
2232
2233 static void
2234 query_sm_resp(proto_tree *tree, tvbuff_t *tvb)
2235 {
2236     int          offset = 0;
2237
2238     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
2239     smpp_handle_time(tree, tvb, hf_smpp_final_date,
2240                                 hf_smpp_final_date_r, &offset);
2241     smpp_handle_int1(tree, tvb, hf_smpp_message_state, &offset);
2242     smpp_handle_int1(tree, tvb, hf_smpp_error_code, &offset);
2243 }
2244
2245 #define bind_transceiver_resp(a, b) bind_receiver_resp(a, b)
2246
2247 static void
2248 submit_sm_resp(proto_tree *tree, tvbuff_t *tvb)
2249 {
2250     int          offset = 0;
2251
2252     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
2253     smpp_handle_tlv(tree, tvb, &offset);
2254 }
2255
2256 #define deliver_sm_resp(a, b) submit_sm_resp(a, b)
2257
2258 static void
2259 submit_multi_resp(proto_tree *tree, tvbuff_t *tvb)
2260 {
2261     int          offset = 0;
2262
2263     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
2264     smpp_handle_dlist_resp(tree, tvb, &offset);
2265     smpp_handle_tlv(tree, tvb, &offset);
2266 }
2267
2268 static void
2269 data_sm_resp(proto_tree *tree, tvbuff_t *tvb)
2270 {
2271     int          offset = 0;
2272
2273     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
2274     smpp_handle_tlv(tree, tvb, &offset);
2275 }
2276
2277 #define broadcast_sm_resp(a, b) submit_sm_resp(a, b)
2278
2279 static void
2280 query_broadcast_sm_resp(proto_tree *tree, tvbuff_t *tvb)
2281 {
2282     int          offset = 0;
2283
2284     smpp_handle_string(tree, tvb, hf_smpp_message_id, &offset);
2285     smpp_handle_tlv(tree, tvb, &offset);
2286 }
2287
2288 /* Huawei SMPP+ extensions */
2289 static void
2290 huawei_auth_acc(proto_tree *tree, tvbuff_t *tvb)
2291 {
2292     int offset = 0;
2293     guint8 version = 0;
2294
2295     smpp_handle_int1(tree, tvb, hf_huawei_smpp_version, &offset);
2296     version = tvb_get_guint8(tvb, offset);
2297     smpp_handle_string(tree, tvb, hf_huawei_smpp_smsc_addr, &offset);
2298     if ( version == '3' ) {
2299         smpp_handle_int1(tree, tvb, hf_huawei_smpp_msc_addr_noa, &offset);
2300         smpp_handle_int1(tree, tvb, hf_huawei_smpp_msc_addr_npi, &offset);
2301         smpp_handle_string(tree, tvb, hf_huawei_smpp_msc_addr, &offset);
2302     }
2303     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
2304     smpp_handle_string(tree, tvb, hf_smpp_destination_addr, &offset);
2305     smpp_handle_int1(tree, tvb, hf_huawei_smpp_mo_mt_flag, &offset);
2306     smpp_handle_string(tree, tvb, hf_huawei_smpp_sm_id, &offset);
2307     smpp_handle_int4(tree, tvb, hf_huawei_smpp_length_auth, &offset);
2308     smpp_handle_int4(tree, tvb, hf_huawei_smpp_service_id, &offset);
2309 }
2310
2311 static void
2312 huawei_auth_acc_resp(proto_tree *tree, tvbuff_t *tvb)
2313 {
2314     int offset = 0;
2315
2316     smpp_handle_int4(tree, tvb, hf_huawei_smpp_operation_result, &offset);
2317     smpp_handle_int1(tree, tvb, hf_huawei_smpp_notify_mode, &offset);
2318 }
2319
2320 static void
2321 huawei_sm_result_notify(proto_tree *tree, tvbuff_t *tvb)
2322 {
2323     int offset = 0;
2324     guint8 version = 0;
2325
2326     smpp_handle_int1(tree, tvb, hf_huawei_smpp_version, &offset);
2327     version = tvb_get_guint8(tvb, offset);
2328     smpp_handle_string(tree, tvb, hf_huawei_smpp_smsc_addr, &offset);
2329
2330     if ( version == '3' ) {
2331         smpp_handle_int1(tree, tvb, hf_huawei_smpp_msc_addr_noa, &offset);
2332         smpp_handle_int1(tree, tvb, hf_huawei_smpp_msc_addr_npi, &offset);
2333         smpp_handle_string(tree, tvb, hf_huawei_smpp_msc_addr, &offset);
2334     }
2335
2336     smpp_handle_string(tree, tvb, hf_smpp_source_addr, &offset);
2337     smpp_handle_string(tree, tvb, hf_smpp_destination_addr, &offset);
2338     smpp_handle_int1(tree, tvb, hf_huawei_smpp_mo_mt_flag, &offset);
2339     smpp_handle_string(tree, tvb, hf_huawei_smpp_sm_id, &offset);
2340     smpp_handle_int4(tree, tvb, hf_huawei_smpp_length_auth, &offset);
2341     smpp_handle_int4(tree, tvb, hf_huawei_smpp_delivery_result, &offset);
2342     smpp_handle_int4(tree, tvb, hf_huawei_smpp_service_id, &offset);
2343 }
2344
2345 static void
2346 huawei_sm_result_notify_resp(proto_tree *tree, tvbuff_t *tvb)
2347 {
2348     int offset = 0;
2349
2350     smpp_handle_int4(tree, tvb, hf_huawei_smpp_operation_result, &offset);
2351 }
2352
2353
2354 /*
2355  * A 'heuristic dissector' that attemtps to establish whether we have
2356  * a genuine SMPP PDU here.
2357  * Only works when:
2358  *      at least the fixed header is there
2359  *      it has a correct overall PDU length
2360  *      it is a 'well-known' operation
2361  *      has a 'well-known' or 'reserved' status
2362  */
2363 static gboolean
2364 dissect_smpp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2365 {
2366     guint        command_id;            /* SMPP command         */
2367     guint        command_status;        /* Status code          */
2368     guint        command_length;        /* length of PDU        */
2369
2370     if (tvb_reported_length(tvb) < SMPP_MIN_LENGTH)     /* Mandatory header     */
2371         return FALSE;
2372     command_length = tvb_get_ntohl(tvb, 0);
2373     if (command_length > 64 * 1024 || command_length < SMPP_MIN_LENGTH)
2374         return FALSE;
2375     command_id = tvb_get_ntohl(tvb, 4);         /* Only known commands  */
2376     if (match_strval(command_id, vals_command_id) == NULL)
2377         return FALSE;
2378     command_status = tvb_get_ntohl(tvb, 8);     /* ..with known status  */
2379     if (match_strval(command_status, vals_command_status) == NULL &&
2380                 match_strrval(command_status, reserved_command_status) == NULL)
2381         return FALSE;
2382     dissect_smpp(tvb, pinfo, tree);
2383     return TRUE;
2384 }
2385
2386 static guint
2387 get_smpp_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
2388 {
2389     return tvb_get_ntohl(tvb, offset);
2390 }
2391
2392 /*
2393  * This global SMPP variable is used to determine whether the PDU to dissect
2394  * is the first SMPP PDU in the packet (or reassembled buffer), requiring
2395  * different column update code than subsequent SMPP PDUs within this packet
2396  * (or reassembled buffer).
2397  *
2398  * FIXME - This approach is NOT dissection multi-thread safe!
2399  */
2400 static gboolean first = TRUE;
2401
2402 static void
2403 dissect_smpp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2404 {
2405     first = TRUE;
2406     if (pinfo->ptype == PT_TCP) {       /* are we running on top of TCP */
2407         tcp_dissect_pdus(tvb, pinfo, tree,
2408                 reassemble_over_tcp,    /* Do we try to reassemble      */
2409                 16,                     /* Length of fixed header       */
2410                 get_smpp_pdu_len,       /* Function returning PDU len   */
2411                 dissect_smpp_pdu);      /* PDU dissector                */
2412     } else {                            /* no? probably X.25            */
2413         guint32 offset = 0;
2414         while (tvb_reported_length_remaining(tvb, offset) > 0) {
2415             guint16 pdu_len = tvb_get_ntohl(tvb, offset);
2416             gint pdu_real_len = tvb_length_remaining(tvb, offset);
2417             tvbuff_t *pdu_tvb;
2418
2419             if (pdu_len < 1)
2420                 THROW(ReportedBoundsError);
2421
2422             if (pdu_real_len <= 0)
2423                 return;
2424             if (pdu_real_len > pdu_len)
2425                 pdu_real_len = pdu_len;
2426             pdu_tvb = tvb_new_subset(tvb, offset, pdu_real_len, pdu_len);
2427             dissect_smpp_pdu(pdu_tvb, pinfo, tree);
2428             offset += pdu_len;
2429             first = FALSE;
2430         }
2431     }
2432 }
2433
2434
2435 /* Dissect a single SMPP PDU contained within "tvb". */
2436 static void
2437 dissect_smpp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2438 {
2439     int          offset = 0;            /* Offset within tvbuff */
2440     guint        command_length;        /* length of PDU        */
2441     guint        command_id;            /* SMPP command         */
2442     guint        command_status;        /* Status code          */
2443     guint        sequence_number;       /* ...of command        */
2444     smpp_tap_rec_t* tap_rec;            /* Tap record           */
2445     const gchar *command_str;
2446     const gchar *command_status_str = NULL;
2447     /* Set up structures needed to add the protocol subtree and manage it */
2448     proto_item  *ti = NULL;
2449     proto_tree  *smpp_tree = NULL;
2450
2451     /*
2452      * Safety: don't even try to dissect the PDU
2453      * when the mandatory header isn't present.
2454      */
2455     if (tvb_reported_length(tvb) < SMPP_MIN_LENGTH)
2456         return;
2457     command_length = tvb_get_ntohl(tvb, offset);
2458     offset += 4;
2459     command_id = tvb_get_ntohl(tvb, offset);
2460     command_str = val_to_str(command_id, vals_command_id,
2461             "(Unknown SMPP Operation 0x%08X)");
2462     offset += 4;
2463     command_status = tvb_get_ntohl(tvb, offset);
2464     if (command_id & 0x80000000) {
2465         /* PDU is a response. */
2466         command_status_str = match_strval(command_status, vals_command_status);
2467         if (command_status_str == NULL) {
2468                 /* Check if the reserved value is in the vendor-specific range. */
2469                 command_status_str = (command_status >= 0x400 && command_status <= 0x4FF ?
2470                                 ep_strdup_printf("Vendor-specific Error (0x%08X)", command_status) :
2471                                 ep_strdup_printf("(Reserved Error 0x%08X)", command_status));
2472         }
2473     }
2474     offset += 4;
2475     sequence_number = tvb_get_ntohl(tvb, offset);
2476     offset += 4;
2477
2478     /*
2479      * Update the protocol column.
2480      */
2481     if (first == TRUE) {
2482         col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMPP");
2483     }
2484
2485     /*
2486      * Create display subtree for the protocol
2487      */
2488     if (tree) {
2489         ti = proto_tree_add_item (tree, proto_smpp, tvb, 0, tvb_length(tvb), ENC_NA);
2490         smpp_tree = proto_item_add_subtree (ti, ett_smpp);
2491     }
2492
2493     /*
2494      * Cycle over the encapsulated PDUs
2495      */
2496     {
2497         tvbuff_t *pdu_tvb;
2498
2499         /*
2500          * Make entries in the Info column on the summary display
2501          */
2502         if (check_col(pinfo->cinfo, COL_INFO)) {
2503             if (first == TRUE) {
2504                 /*
2505                  * First PDU - We already computed the fixed header
2506                  */
2507                 col_clear(pinfo->cinfo, COL_INFO);
2508                 col_add_fstr(pinfo->cinfo, COL_INFO, "SMPP %s", command_str);
2509                 first = FALSE;
2510             } else {
2511                 /*
2512                  * Subsequent PDUs
2513                  */
2514                 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", command_str);
2515             }
2516             /*
2517              * Display command status of responses in Info column
2518              */
2519             if (command_id & 0x80000000) {
2520                 col_append_fstr(pinfo->cinfo, COL_INFO, ": \"%s\"",
2521                         command_status_str);
2522             }
2523         }
2524
2525         /*
2526          * Create a tvb for the current PDU.
2527          * Physical length: at most command_length
2528          * Reported length: command_length
2529          */
2530         if (tvb_length_remaining(tvb, offset - 16 + command_length) > 0) {
2531             pdu_tvb = tvb_new_subset(tvb, offset - 16,
2532                     command_length,     /* Physical length */
2533                     command_length);    /* Length reported by the protocol */
2534         } else {
2535             pdu_tvb = tvb_new_subset(tvb, offset - 16,
2536                     tvb_length_remaining(tvb, offset - 16),/* Physical length */
2537                     command_length);    /* Length reported by the protocol */
2538         }
2539
2540         /*
2541          * Dissect the PDU
2542          *
2543          * If "tree" is NULL, Wireshark is only interested in creation
2544          * of conversations, reassembly and subdissection but not in
2545          * the detailed protocol tree.
2546          * In the interest of speed, skip the generation of protocol tree
2547          * items when "tree" is NULL.
2548          *
2549          * The only PDU which requires subdissection currently is the
2550          * sm_submit PDU (command ID = 0x00000004).
2551          */
2552         if (tree || (command_id == 4))
2553         {
2554             /*
2555              * Create display subtree for the PDU
2556              */
2557             if (tree) {
2558                 proto_tree_add_uint(smpp_tree, hf_smpp_command_length,
2559                         pdu_tvb, 0, 4, command_length);
2560                 proto_tree_add_uint(smpp_tree, hf_smpp_command_id,
2561                         pdu_tvb, 4, 4, command_id);
2562                 proto_item_append_text(ti, ", Command: %s", command_str);
2563
2564                 /*
2565                  * Status is only meaningful with responses
2566                  */
2567                 if (command_id & 0x80000000) {
2568                     proto_tree_add_uint(smpp_tree, hf_smpp_command_status,
2569                             pdu_tvb, 8, 4, command_status);
2570                     proto_item_append_text (ti, ", Status: \"%s\"",
2571                             command_status_str);
2572                 }
2573                 proto_tree_add_uint(smpp_tree, hf_smpp_sequence_number,
2574                         pdu_tvb, 12, 4, sequence_number);
2575                 proto_item_append_text(ti, ", Seq: %u, Len: %u",
2576                         sequence_number, command_length);
2577             }
2578
2579             /*
2580              * End of fixed header.
2581              * Don't dissect variable part if it is shortened.
2582              *
2583              * FIXME - We then do not report a Short Frame or Malformed Packet
2584              */
2585             if (command_length <= tvb_reported_length(pdu_tvb))
2586             {
2587                 tvbuff_t *tmp_tvb = tvb_new_subset(pdu_tvb, 16,
2588                         -1, command_length - 16);
2589                 if (command_id & 0x80000000)
2590                 {
2591                     switch (command_id & 0x7FFFFFFF) {
2592                         /*
2593                          * All of these only have a fixed header
2594                          */
2595                         case   0:       /* Generic nack         */
2596                         case   6:       /* Unbind resp          */
2597                         case   7:       /* Replace SM resp      */
2598                         case   8:       /* Cancel SM resp       */
2599                         case  21:       /* Enquire link resp    */
2600                         case 275:       /* Cancel Broadcast SM resp */
2601                             break;
2602                         /* FIXME: The body of the response PDUs are only
2603                          * only dissected if the request was successful.
2604                          * However, in SMPP 5.0 some responses might
2605                          * contain body to provide additional information
2606                          * about the error. This needs to be handled.
2607                          */
2608                         case   1:
2609                             if (!command_status)
2610                                 bind_receiver_resp(smpp_tree, tmp_tvb);
2611                             break;
2612                         case   2:
2613                             if (!command_status)
2614                                 bind_transmitter_resp(smpp_tree, tmp_tvb);
2615                             break;
2616                         case   3:
2617                             if (!command_status)
2618                                 query_sm_resp(smpp_tree, tmp_tvb);
2619                             break;
2620                         case   4:
2621                             if (!command_status)
2622                                 submit_sm_resp(smpp_tree, tmp_tvb);
2623                             break;
2624                         case   5:
2625                             if (!command_status)
2626                                 deliver_sm_resp(smpp_tree, tmp_tvb);
2627                             break;
2628                         case   9:
2629                             if (!command_status)
2630                                 bind_transceiver_resp(smpp_tree, tmp_tvb);
2631                             break;
2632                         case  33:
2633                             if (!command_status)
2634                                 submit_multi_resp(smpp_tree, tmp_tvb);
2635                             break;
2636                         case 259:
2637                             if (!command_status)
2638                                 data_sm_resp(smpp_tree, tmp_tvb);
2639                             break;
2640                         case 273:
2641                             if (!command_status)
2642                                 broadcast_sm_resp(smpp_tree, tmp_tvb);
2643                             break;
2644                         case 274:
2645                             if (!command_status)
2646                                 query_broadcast_sm_resp(smpp_tree, tmp_tvb);
2647                             break;
2648                         case 16777217:
2649                             if (!command_status)
2650                                 huawei_auth_acc_resp(smpp_tree, tmp_tvb);
2651                             break;
2652                          case 16777218:
2653                             if (!command_status)
2654                                 huawei_sm_result_notify_resp(smpp_tree, tmp_tvb);
2655                             break;
2656                         default:
2657                             break;
2658                     } /* switch (command_id & 0x7FFFFFFF) */
2659                 }
2660                 else
2661                 {
2662                     switch (command_id) {
2663                         case   1:
2664                             bind_receiver(smpp_tree, tmp_tvb);
2665                             break;
2666                         case   2:
2667                             bind_transmitter(smpp_tree, tmp_tvb);
2668                             break;
2669                         case   3:
2670                             query_sm(smpp_tree, tmp_tvb);
2671                             break;
2672                         case   4:
2673                             submit_sm(smpp_tree, tmp_tvb, pinfo, tree);
2674                             break;
2675                         case   5:
2676                             deliver_sm(smpp_tree, tmp_tvb, pinfo, tree);
2677                             break;
2678                         case   6:       /* Unbind               */
2679                         case  21:       /* Enquire link         */
2680                             break;
2681                         case   7:
2682                             replace_sm(smpp_tree, tmp_tvb);
2683                             break;
2684                         case   8:
2685                             cancel_sm(smpp_tree, tmp_tvb);
2686                             break;
2687                         case   9:
2688                             bind_transceiver(smpp_tree, tmp_tvb);
2689                             break;
2690                         case  11:
2691                             outbind(smpp_tree, tmp_tvb);
2692                             break;
2693                         case  33:
2694                             submit_multi(smpp_tree, tmp_tvb);
2695                             break;
2696                         case  258:
2697                             alert_notification(smpp_tree, tmp_tvb);
2698                             break;
2699                         case  259:
2700                             data_sm(smpp_tree, tmp_tvb);
2701                             break;
2702                         case 273:
2703                             broadcast_sm(smpp_tree, tmp_tvb);
2704                             break;
2705                         case 274:
2706                             query_broadcast_sm(smpp_tree, tmp_tvb);
2707                             break;
2708                         case 275:
2709                             cancel_broadcast_sm(smpp_tree, tmp_tvb);
2710                             break;
2711                         case  16777217:
2712                             huawei_auth_acc(smpp_tree, tmp_tvb);
2713                             break;
2714                         case  16777218:
2715                             huawei_sm_result_notify(smpp_tree, tmp_tvb);
2716                             break;
2717                         default:
2718                             break;
2719                     } /* switch (command_id) */
2720                 } /* if (command_id & 0x80000000) */
2721
2722             } /* if (command_length <= tvb_reported_length(pdu_tvb)) */
2723             offset += command_length;
2724         } /* if (tree || (command_id == 4)) */
2725
2726         /* Queue packet for Tap */
2727         tap_rec = ep_alloc0(sizeof(smpp_tap_rec_t));
2728         tap_rec->command_id = command_id;
2729         tap_rec->command_status = command_status;
2730         tap_queue_packet(smpp_tap, pinfo, tap_rec);
2731
2732         first = FALSE;
2733     }
2734
2735     return;
2736 }
2737
2738
2739 /* Register the protocol with Wireshark */
2740 void
2741 proto_register_smpp(void)
2742 {
2743     module_t *smpp_module; /* Preferences for SMPP */
2744
2745     /* Setup list of header fields      */
2746     static hf_register_info hf[] = {
2747         {   &hf_smpp_command_length,
2748             {   "Length", "smpp.command_length",
2749                 FT_UINT32, BASE_DEC, NULL, 0x00,
2750                 "Total length of the SMPP PDU.",
2751                 HFILL
2752             }
2753         },
2754         {   &hf_smpp_command_id,
2755             {   "Operation", "smpp.command_id",
2756                 FT_UINT32, BASE_HEX, VALS(vals_command_id), 0x00,
2757                 "Defines the SMPP PDU.",
2758                 HFILL
2759             }
2760         },
2761         {   &hf_smpp_command_status,
2762             {   "Result", "smpp.command_status",
2763                 FT_UINT32, BASE_HEX, VALS(vals_command_status), 0x00,
2764                 "Indicates success or failure of the SMPP request.",
2765                 HFILL
2766             }
2767         },
2768         {   &hf_smpp_sequence_number,
2769             {   "Sequence #", "smpp.sequence_number",
2770                 FT_UINT32, BASE_DEC, NULL, 0x00,
2771                 "A number to correlate requests with responses.",
2772                 HFILL
2773             }
2774         },
2775         {   &hf_smpp_system_id,
2776             {   "System ID", "smpp.system_id",
2777                 FT_STRING, BASE_NONE, NULL, 0x00,
2778                 "Identifies a system.",
2779                 HFILL
2780             }
2781         },
2782         {   &hf_smpp_password,
2783             {   "Password", "smpp.password",
2784                 FT_STRING, BASE_NONE, NULL, 0x00,
2785                 "Password used for authentication.",
2786                 HFILL
2787             }
2788         },
2789         {   &hf_smpp_system_type,
2790             {   "System type", "smpp.system_type",
2791                 FT_STRING, BASE_NONE, NULL, 0x00,
2792                 "Categorizes the system.",
2793                 HFILL
2794             }
2795         },
2796         {   &hf_smpp_interface_version,
2797             {   "Version (if)", "smpp.interface_version",
2798                 FT_STRING, BASE_NONE, NULL, 0x00,
2799                 "Version of SMPP interface supported.",
2800                 HFILL
2801             }
2802         },
2803         {   &hf_smpp_service_type,
2804             {   "Service type", "smpp.service_type",
2805                 FT_STRING, BASE_NONE, NULL, 0x00,
2806                 "SMS application service associated with the message.",
2807                 HFILL
2808             }
2809         },
2810         {   &hf_smpp_addr_ton,
2811             {   "Type of number", "smpp.addr_ton",
2812                 FT_UINT8, BASE_HEX, VALS(vals_addr_ton), 0x00,
2813                 "Indicates the type of number, given in the address.",
2814                 HFILL
2815             }
2816         },
2817         {   &hf_smpp_source_addr_ton,
2818             {   "Type of number (originator)", "smpp.source_addr_ton",
2819                 FT_UINT8, BASE_HEX, VALS(vals_addr_ton), 0x00,
2820                 "Indicates originator type of number, given in the address.",
2821                 HFILL
2822             }
2823         },
2824         {   &hf_smpp_dest_addr_ton,
2825             {   "Type of number (recipient)", "smpp.dest_addr_ton",
2826                 FT_UINT8, BASE_HEX, VALS(vals_addr_ton), 0x00,
2827                 "Indicates recipient type of number, given in the address.",
2828                 HFILL
2829             }
2830         },
2831         {   &hf_smpp_addr_npi,
2832             {   "Numbering plan indicator", "smpp.addr_npi",
2833                 FT_UINT8, BASE_HEX, VALS(vals_addr_npi), 0x00,
2834                 "Gives the numbering plan this address belongs to.",
2835                 HFILL
2836             }
2837         },
2838         {   &hf_smpp_source_addr_npi,
2839             {   "Numbering plan indicator (originator)", "smpp.source_addr_npi",
2840                 FT_UINT8, BASE_HEX, VALS(vals_addr_npi), 0x00,
2841                 "Gives originator numbering plan this address belongs to.",
2842                 HFILL
2843             }
2844         },
2845         {   &hf_smpp_dest_addr_npi,
2846             {   "Numbering plan indicator (recipient)", "smpp.dest_addr_npi",
2847                 FT_UINT8, BASE_HEX, VALS(vals_addr_npi), 0x00,
2848                 "Gives recipient numbering plan this address belongs to.",
2849                 HFILL
2850             }
2851         },
2852         {   &hf_smpp_address_range,
2853             {   "Address", "smpp.address_range",
2854                 FT_STRING, BASE_NONE, NULL, 0x00,
2855                 "Given address or address range.",
2856                 HFILL
2857             }
2858         },
2859         {   &hf_smpp_source_addr,
2860             {   "Originator address", "smpp.source_addr",
2861                 FT_STRING, BASE_NONE, NULL, 0x00,
2862                 "Address of SME originating this message.",
2863                 HFILL
2864             }
2865         },
2866         {   &hf_smpp_destination_addr,
2867             {   "Recipient address", "smpp.destination_addr",
2868                 FT_STRING, BASE_NONE, NULL, 0x00,
2869                 "Address of SME receiving this message.",
2870                 HFILL
2871             }
2872         },
2873         {   &hf_smpp_esm_submit_msg_mode,
2874             {   "Messaging mode", "smpp.esm.submit.msg_mode",
2875                 FT_UINT8, BASE_HEX, VALS(vals_esm_submit_msg_mode), 0x03,
2876                 "Mode attribute for this message.",
2877                 HFILL
2878             }
2879         },
2880         {   &hf_smpp_esm_submit_msg_type,
2881             {   "Message type", "smpp.esm.submit.msg_type",
2882                 FT_UINT8, BASE_HEX, VALS(vals_esm_submit_msg_type), 0x3C,
2883                 "Type attribute for this message.",
2884                 HFILL
2885             }
2886         },
2887         {   &hf_smpp_esm_submit_features,
2888             {   "GSM features", "smpp.esm.submit.features",
2889                 FT_UINT8, BASE_HEX, VALS(vals_esm_submit_features), 0xC0,
2890                 "GSM network specific features.",
2891                 HFILL
2892             }
2893         },
2894         /*! \todo Get proper values from GSM-spec.      */
2895         {   &hf_smpp_protocol_id,
2896             {   "Protocol id.", "smpp.protocol_id",
2897                 FT_UINT8, BASE_HEX, NULL, 0x00,
2898                 "Protocol identifier according GSM 03.40.",
2899                 HFILL
2900             }
2901         },
2902         {   &hf_smpp_priority_flag,
2903             {   "Priority level", "smpp.priority_flag",
2904                 FT_UINT8, BASE_HEX, VALS(vals_priority_flag), 0x00,
2905                 "The priority level of the short message.",
2906                 HFILL
2907             }
2908         },
2909         {   &hf_smpp_schedule_delivery_time,
2910             {   "Scheduled delivery time", "smpp.schedule_delivery_time",
2911                 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x00,
2912                 "Scheduled time for delivery of short message.",
2913                 HFILL
2914             }
2915         },
2916         {   &hf_smpp_schedule_delivery_time_r,
2917             {   "Scheduled delivery time", "smpp.schedule_delivery_time_r",
2918                 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
2919                 "Scheduled time for delivery of short message.",
2920                 HFILL
2921             }
2922         },
2923         {   &hf_smpp_validity_period,
2924             {   "Validity period", "smpp.validity_period",
2925                 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x00,
2926                 "Validity period of this message.",
2927                 HFILL
2928             }
2929         },
2930         {   &hf_smpp_validity_period_r,
2931             {   "Validity period", "smpp.validity_period_r",
2932                 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
2933                 "Validity period of this message.",
2934                 HFILL
2935             }
2936         },
2937         {   &hf_smpp_regdel_receipt,
2938             {   "Delivery receipt", "smpp.regdel.receipt",
2939                 FT_UINT8, BASE_HEX, VALS(vals_regdel_receipt), 0x03,
2940                 "SMSC delivery receipt request.",
2941                 HFILL
2942             }
2943         },
2944         {   &hf_smpp_regdel_acks,
2945             {   "Message type", "smpp.regdel.acks",
2946                 FT_UINT8, BASE_HEX, VALS(vals_regdel_acks), 0x0C,
2947                 "SME acknowledgement request.",
2948                 HFILL
2949             }
2950         },
2951         {   &hf_smpp_regdel_notif,
2952             {   "Intermediate notif", "smpp.regdel.notif",
2953                 FT_UINT8, BASE_HEX, VALS(vals_regdel_notif), 0x10,
2954                 "Intermediate notification request.",
2955                 HFILL
2956             }
2957         },
2958         {   &hf_smpp_replace_if_present_flag,
2959             {   "Replace", "smpp.replace_if_present_flag",
2960                 FT_UINT8, BASE_HEX, VALS(vals_replace_if_present_flag), 0x01,
2961                 "Replace the short message with this one or not.",
2962                 HFILL
2963             }
2964         },
2965         {   &hf_smpp_data_coding,
2966             {   "Data coding", "smpp.data_coding",
2967                 FT_UINT8, BASE_HEX, NULL, 0x00,
2968                 "Defines the encoding scheme of the message.",
2969                 HFILL
2970             }
2971         },
2972         {   &hf_smpp_sm_default_msg_id,
2973             {   "Predefined message", "smpp.sm_default_msg_id",
2974                 FT_UINT8, BASE_DEC, NULL, 0x00,
2975                 "Index of a predefined ('canned') short message.",
2976                 HFILL
2977             }
2978         },
2979         {   &hf_smpp_sm_length,
2980             {   "Message length", "smpp.sm_length",
2981                 FT_UINT8, BASE_DEC, NULL, 0x00,
2982                 "Length of the message content.",
2983                 HFILL
2984             }
2985         },
2986         {   &hf_smpp_short_message,
2987             {   "Message", "smpp.message",
2988                 FT_NONE, BASE_NONE, NULL, 0x00,
2989                 "The actual message or data.",
2990                 HFILL
2991             }
2992         },
2993         {   &hf_smpp_message_id,
2994             {   "Message id.", "smpp.message_id",
2995                 FT_STRING, BASE_NONE, NULL, 0x00,
2996                 "Identifier of the submitted short message.",
2997                 HFILL
2998             }
2999         },
3000         {   &hf_smpp_dlist,
3001             {   "Destination list", "smpp.dlist",
3002                 FT_NONE, BASE_NONE, NULL, 0x00,
3003                 "The list of destinations for a short message.",
3004                 HFILL
3005             }
3006         },
3007         {   &hf_smpp_dlist_resp,
3008             {   "Unsuccessful delivery list", "smpp.dlist_resp",
3009                 FT_NONE, BASE_NONE, NULL, 0x00,
3010                 "The list of unsuccessful deliveries to destinations.",
3011                 HFILL
3012             }
3013         },
3014         {   &hf_smpp_dl_name,
3015             {   "Distr. list name", "smpp.dl_name",
3016                 FT_STRING, BASE_NONE, NULL, 0x00,
3017                 "The name of the distribution list.",
3018                 HFILL
3019             }
3020         },
3021         {   &hf_smpp_final_date,
3022             {   "Final date", "smpp.final_date",
3023                 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x00,
3024                 "Date-time when the queried message reached a final state.",
3025                 HFILL
3026             }
3027         },
3028         {   &hf_smpp_final_date_r,
3029             {   "Final date", "smpp.final_date_r",
3030                 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
3031                 "Date-time when the queried message reached a final state.",
3032                 HFILL
3033             }
3034         },
3035         {   &hf_smpp_message_state,
3036             {   "Message state", "smpp.message_state",
3037                 FT_UINT8, BASE_DEC, VALS(vals_message_state), 0x00,
3038                 "Specifies the status of the queried short message.",
3039                 HFILL
3040             }
3041         },
3042         {   &hf_smpp_error_code,
3043             {   "Error code", "smpp.error_code",
3044                 FT_UINT8, BASE_DEC, NULL, 0x00,
3045                 "Network specific error code defining reason for failure.",
3046                 HFILL
3047             }
3048         },
3049         {   &hf_smpp_error_status_code,
3050             {   "Status", "smpp.error_status_code",
3051                 FT_UINT32, BASE_HEX, VALS(vals_command_status), 0x00,
3052                 "Indicates success/failure of request for this address.",
3053                 HFILL
3054             }
3055         },
3056         {   &hf_smpp_esme_addr_ton,
3057             {   "Type of number (ESME)", "smpp.esme_addr_ton",
3058                 FT_UINT8, BASE_HEX, VALS(vals_addr_ton), 0x00,
3059                 "Indicates recipient type of number, given in the address.",
3060                 HFILL
3061             }
3062         },
3063         {   &hf_smpp_esme_addr_npi,
3064             {   "Numbering plan indicator (ESME)", "smpp.esme_addr_npi",
3065                 FT_UINT8, BASE_HEX, VALS(vals_addr_npi), 0x00,
3066                 "Gives the numbering plan this address belongs to.",
3067                 HFILL
3068             }
3069         },
3070         {   &hf_smpp_esme_addr,
3071             {   "ESME address", "smpp.esme_addr",
3072                 FT_STRING, BASE_NONE, NULL, 0x00,
3073                 "Address of ESME originating this message.",
3074                 HFILL
3075             }
3076         },
3077         {   &hf_smpp_dest_addr_subunit,
3078             {   "Subunit destination", "smpp.dest_addr_subunit",
3079                 FT_UINT8, BASE_HEX, VALS(vals_addr_subunit), 0x00,
3080                 "Subunit address within mobile to route message to.",
3081                 HFILL
3082             }
3083         },
3084         {   &hf_smpp_source_addr_subunit,
3085             {   "Subunit origin", "smpp.source_addr_subunit",
3086                 FT_UINT8, BASE_HEX, VALS(vals_addr_subunit), 0x00,
3087                 "Subunit address within mobile that generated the message.",
3088                 HFILL
3089             }
3090         },
3091         {   &hf_smpp_dest_network_type,
3092             {   "Destination network", "smpp.dest_network_type",
3093                 FT_UINT8, BASE_HEX, VALS(vals_network_type), 0x00,
3094                 "Network associated with the destination address.",
3095                 HFILL
3096             }
3097         },
3098         {   &hf_smpp_source_network_type,
3099             {   "Originator network", "smpp.source_network_type",
3100                 FT_UINT8, BASE_HEX, VALS(vals_network_type), 0x00,
3101                 "Network associated with the originator address.",
3102                 HFILL
3103             }
3104         },
3105         {   &hf_smpp_dest_bearer_type,
3106             {   "Destination bearer", "smpp.dest_bearer_type",
3107                 FT_UINT8, BASE_HEX, VALS(vals_bearer_type), 0x00,
3108                 "Desired bearer for delivery of message.",
3109                 HFILL
3110             }
3111         },
3112         {   &hf_smpp_source_bearer_type,
3113             {   "Originator bearer", "smpp.source_bearer_type",
3114                 FT_UINT8, BASE_HEX, VALS(vals_bearer_type), 0x00,
3115                 "Bearer over which the message originated.",
3116                 HFILL
3117             }
3118         },
3119         {   &hf_smpp_dest_telematics_id,
3120             {   "Telematic interworking (dest)", "smpp.dest_telematics_id",
3121                 FT_UINT16, BASE_HEX, NULL, 0x00,
3122                 "Telematic interworking to be used for message delivery.",
3123                 HFILL
3124             }
3125         },
3126         {   &hf_smpp_source_telematics_id,
3127             {   "Telematic interworking (orig)", "smpp.source_telematics_id",
3128                 FT_UINT16, BASE_HEX, NULL, 0x00,
3129                 "Telematic interworking used for message submission.",
3130                 HFILL
3131             }
3132         },
3133         {   &hf_smpp_qos_time_to_live,
3134             {   "Validity period", "smpp.qos_time_to_live",
3135                 FT_UINT32, BASE_DEC, NULL, 0x00,
3136                 "Number of seconds to retain message before expiry.",
3137                 HFILL
3138             }
3139         },
3140         {   &hf_smpp_payload_type,
3141             {   "Payload", "smpp.payload_type",
3142                 FT_UINT8, BASE_DEC, VALS(vals_payload_type), 0x00,
3143                 "PDU type contained in the message payload.",
3144                 HFILL
3145             }
3146         },
3147         {   &hf_smpp_additional_status_info_text,
3148             {   "Information", "smpp.additional_status_info_text",
3149                 FT_STRING, BASE_NONE, NULL, 0x00,
3150                 "Description of the meaning of a response PDU.",
3151                 HFILL
3152             }
3153         },
3154         {   &hf_smpp_receipted_message_id,
3155             {   "SMSC identifier", "smpp.receipted_message_id",
3156                 FT_STRING, BASE_NONE, NULL, 0x00,
3157                 "SMSC handle of the message being received.",
3158                 HFILL
3159             }
3160         },
3161         {   &hf_smpp_privacy_indicator,
3162             {   "Privacy indicator", "smpp.privacy_indicator",
3163                 FT_UINT8, BASE_DEC, VALS(vals_privacy_indicator), 0x00,
3164                 "Indicates the privacy level of the message.",
3165                 HFILL
3166             }
3167         },
3168     {   &hf_smpp_source_subaddress,
3169             {   "Source Subaddress", "smpp.source_subaddress",
3170                 FT_BYTES, BASE_NONE, NULL, 0x00,
3171                 NULL,
3172                 HFILL
3173             }
3174         },
3175     {   &hf_smpp_dest_subaddress,
3176             {   "Destination Subaddress", "smpp.dest_subaddress",
3177                 FT_BYTES, BASE_NONE, NULL, 0x00,
3178                 NULL,
3179                 HFILL
3180             }
3181         },
3182     {   &hf_smpp_user_message_reference,
3183             {   "Message reference", "smpp.user_message_reference",
3184                 FT_UINT16, BASE_HEX, NULL, 0x00,
3185                 "Reference to the message, assigned by the user.",
3186                 HFILL
3187             }
3188         },
3189         {   &hf_smpp_user_response_code,
3190             {   "Application response code", "smpp.user_response_code",
3191                 FT_UINT8, BASE_HEX, NULL, 0x00,
3192                 "A response code set by the user.",
3193                 HFILL
3194             }
3195         },
3196         {   &hf_smpp_language_indicator,
3197             {   "Language", "smpp.language_indicator",
3198                 FT_UINT8, BASE_DEC, VALS(vals_language_indicator), 0x00,
3199                 "Indicates the language of the short message.",
3200                 HFILL
3201             }
3202         },
3203         {   &hf_smpp_source_port,
3204             {   "Source port", "smpp.source_port",
3205                 FT_UINT16, BASE_HEX, NULL, 0x00,
3206                 "Application port associated with the source of the message.",
3207                 HFILL
3208             }
3209         },
3210         {   &hf_smpp_destination_port,
3211             {   "Destination port", "smpp.destination_port",
3212                 FT_UINT16, BASE_HEX, NULL, 0x00,
3213                 "Application port associated with the destination of the message.",
3214                 HFILL
3215             }
3216         },
3217         {   &hf_smpp_sar_msg_ref_num,
3218             {   "SAR reference number", "smpp.sar_msg_ref_num",
3219                 FT_UINT16, BASE_DEC, NULL, 0x00,
3220                 "Reference number for a concatenated short message.",
3221                 HFILL
3222             }
3223         },
3224         {   &hf_smpp_sar_total_segments,
3225             {   "SAR size", "smpp.sar_total_segments",
3226                 FT_UINT16, BASE_DEC, NULL, 0x00,
3227                 "Number of segments of a concatenated short message.",
3228                 HFILL
3229             }
3230         },
3231         {   &hf_smpp_sar_segment_seqnum,
3232             {   "SAR sequence number", "smpp.sar_segment_seqnum",
3233                 FT_UINT8, BASE_DEC, NULL, 0x00,
3234                 "Segment number within a concatenated short message.",
3235                 HFILL
3236             }
3237         },
3238         {   &hf_smpp_display_time,
3239             {   "Display time", "smpp.display_time",
3240                 FT_UINT8, BASE_DEC, VALS(vals_display_time), 0x00,
3241                 "Associates a display time with the message on the handset.",
3242                 HFILL
3243             }
3244         },
3245         {   &hf_smpp_sms_signal,
3246             {   "SMS signal", "smpp.sms_signal",
3247                 FT_UINT16, BASE_HEX, NULL, 0x00,
3248                 "Alert the user according to the information contained within this information element.",
3249                 HFILL
3250             }
3251         },
3252         {   &hf_smpp_ms_validity,
3253             {   "Validity info", "smpp.ms_validity",
3254                 FT_UINT8, BASE_DEC, VALS(vals_ms_validity), 0x00,
3255                 "Associates validity info with the message on the handset.",
3256                 HFILL
3257             }
3258         },
3259         {   &hf_smpp_dpf_result,
3260             {   "Delivery pending set?", "smpp.dpf_result",
3261                 FT_UINT8, BASE_DEC, VALS(vals_dpf_result), 0x00,
3262                 "Indicates whether Delivery Pending Flag was set.",
3263                 HFILL
3264             }
3265         },
3266         {   &hf_smpp_set_dpf,
3267             {   "Request DPF set", "smpp.set_dpf",
3268                 FT_UINT8, BASE_DEC, VALS(vals_set_dpf), 0x00,
3269                 "Request to set the DPF for certain failure scenario's.",
3270                 HFILL
3271             }
3272         },
3273         {   &hf_smpp_ms_availability_status,
3274             {   "Availability status", "smpp.ms_availability_status",
3275                 FT_UINT8, BASE_DEC, VALS(vals_ms_availability_status), 0x00,
3276                 "Indicates the availability state of the handset.",
3277                 HFILL
3278             }
3279         },
3280         {   &hf_smpp_delivery_failure_reason,
3281             {   "Delivery failure reason", "smpp.delivery_failure_reason",
3282                 FT_UINT8, BASE_DEC, VALS(vals_delivery_failure_reason), 0x00,
3283                 "Indicates the reason for a failed delivery attempt.",
3284                 HFILL
3285             }
3286         },
3287         {   &hf_smpp_more_messages_to_send,
3288             {   "More messages?", "smpp.more_messages_to_send",
3289                 FT_UINT8, BASE_DEC, VALS(vals_more_messages_to_send), 0x00,
3290                 "Indicates more messages pending for the same destination.",
3291                 HFILL
3292             }
3293         },
3294         {   &hf_smpp_number_of_messages,
3295             {   "Number of messages", "smpp.number_of_messages",
3296                 FT_UINT8, BASE_DEC, NULL, 0x00,
3297                 "Indicates number of messages stored in a mailbox.",
3298                 HFILL
3299             }
3300         },
3301         {   &hf_smpp_its_reply_type,
3302             {   "Reply method", "smpp.its_reply_type",
3303                 FT_UINT8, BASE_DEC, VALS(vals_its_reply_type), 0x00,
3304                 "Indicates the handset reply method on message receipt.",
3305                 HFILL
3306             }
3307         },
3308         {   &hf_smpp_ussd_service_op,
3309             {   "USSD service operation", "smpp.ussd_service_op",
3310                 FT_UINT8, BASE_DEC, VALS(vals_ussd_service_op), 0x00,
3311                 "Indicates the USSD service operation.",
3312                 HFILL
3313             }
3314         },
3315         {   &hf_smpp_vendor_op,
3316             {   "Value", "smpp.vendor_op",
3317                 FT_BYTES, BASE_NONE, NULL, 0x00,
3318                 "A supplied optional parameter specific to an SMSC-vendor.",
3319                 HFILL
3320             }
3321         },
3322         {   &hf_smpp_reserved_op,
3323             {   "Value", "smpp.reserved_op",
3324                 FT_BYTES, BASE_NONE, NULL, 0x00,
3325                 "An optional parameter that is reserved in this version.",
3326                 HFILL
3327             }
3328         },
3329         {   &hf_smpp_msg_wait_ind,
3330             {   "Indication", "smpp.msg_wait.ind",
3331                 FT_UINT8, BASE_HEX, VALS(vals_msg_wait_ind), 0x80,
3332                 "Indicates to the handset that a message is waiting.",
3333                 HFILL
3334             }
3335         },
3336         {   &hf_smpp_msg_wait_type,
3337             {   "Type", "smpp.msg_wait.type",
3338                 FT_UINT8, BASE_HEX, VALS(vals_msg_wait_type), 0x03,
3339                 "Indicates type of message that is waiting.",
3340                 HFILL
3341             }
3342         },
3343         {   &hf_smpp_SC_interface_version,
3344             {   "SMSC-supported version", "smpp.SC_interface_version",
3345                 FT_STRING, BASE_NONE, NULL, 0x00,
3346                 "Version of SMPP interface supported by the SMSC.",
3347                 HFILL
3348             }
3349         },
3350         {   &hf_smpp_callback_num_pres,
3351             {   "Presentation", "smpp.callback_num.pres",
3352                 FT_UINT8, BASE_HEX, VALS(vals_callback_num_pres), 0x0C,
3353                 "Controls the presentation indication.",
3354                 HFILL
3355             }
3356         },
3357         {   &hf_smpp_callback_num_scrn,
3358             {   "Screening", "smpp.callback_num.scrn",
3359                 FT_UINT8, BASE_HEX, VALS(vals_callback_num_scrn), 0x03,
3360                 "Controls screening of the callback-number.",
3361                 HFILL
3362             }
3363         },
3364         {   &hf_smpp_callback_num_atag,
3365             {   "Callback number - alphanumeric display tag",
3366                 "smpp.callback_num_atag",
3367                 FT_NONE, BASE_NONE, NULL, 0x00,
3368                 "Associates an alphanumeric display with call back number.",
3369                 HFILL
3370             }
3371         },
3372         {   &hf_smpp_callback_num,
3373             {   "Callback number", "smpp.callback_num",
3374                 FT_NONE, BASE_NONE, NULL, 0x00,
3375                 "Associates a call back number with the message.",
3376                 HFILL
3377             }
3378         },
3379         {   &hf_smpp_network_error_type,
3380             {   "Error type", "smpp.network_error.type",
3381                 FT_UINT8, BASE_DEC, VALS(vals_network_error_type), 0x00,
3382                 "Indicates the network type.",
3383                 HFILL
3384             }
3385         },
3386         {   &hf_smpp_network_error_code,
3387             {   "Error code", "smpp.network_error.code",
3388                 FT_UINT16, BASE_HEX, NULL, 0x00,
3389                 "Gives the actual network error code.",
3390                 HFILL
3391             }
3392         },
3393         {   &hf_smpp_message_payload,
3394             {   "Payload", "smpp.message_payload",
3395                 FT_NONE, BASE_NONE, NULL, 0x00,
3396                 "Short message user data.",
3397                 HFILL
3398             }
3399         },
3400         {   &hf_smpp_alert_on_message_delivery_null,
3401             {   "Alert on delivery", "smpp.alert_on_message_delivery",
3402                 FT_NONE, BASE_NONE, NULL, 0x00,
3403                 "Instructs the handset to alert user on message delivery.",
3404                 HFILL
3405             }
3406         },
3407         {   &hf_smpp_alert_on_message_delivery,
3408             {   "Alert on delivery", "smpp.alert_on_message_delivery",
3409                 FT_UINT8, BASE_DEC, VALS(vals_alert_on_message_delivery), 0x00,
3410                 "Instructs the handset to alert user on message delivery.",
3411                 HFILL
3412             }
3413         },
3414         {   &hf_smpp_its_session_number,
3415             {   "Session number", "smpp.its_session.number",
3416                 FT_UINT8, BASE_DEC, NULL, 0x00,
3417                 "Session number of interactive teleservice.",
3418                 HFILL
3419             }
3420         },
3421         {   &hf_smpp_its_session_sequence,
3422             {   "Sequence number", "smpp.its_session.sequence",
3423                 FT_UINT8, BASE_HEX, NULL, 0xFE,
3424                 "Sequence number of the dialogue unit.",
3425                 HFILL
3426             }
3427         },
3428         {   &hf_smpp_its_session_ind,
3429             {   "Session indicator", "smpp.its_session.ind",
3430                 FT_UINT8, BASE_HEX, VALS(vals_its_session_ind), 0x01,
3431                 "Indicates whether this message is end of conversation.",
3432                 HFILL
3433             }
3434         },
3435         {   &hf_smpp_opt_params,
3436             {   "Optional parameters", "smpp.opt_params",
3437                 FT_NONE, BASE_NONE, NULL, 0x00,
3438                 "The list of optional parameters in this operation.",
3439                 HFILL
3440             }
3441         },
3442         {   &hf_smpp_opt_param,
3443             {   "Optional parameter", "smpp.opt_param",
3444                 FT_NONE, BASE_NONE, NULL, 0x00,
3445                 NULL,
3446                 HFILL
3447             }
3448         },
3449         {   &hf_smpp_opt_param_tag,
3450             {   "Tag", "smpp.opt_param_tag",
3451                 FT_UINT16, BASE_HEX, NULL, 0x00,
3452                 "Optional parameter identifier tag",
3453                 HFILL
3454             }
3455         },
3456         {   &hf_smpp_opt_param_len,
3457             {   "Length", "smpp.opt_param_len",
3458                 FT_UINT16, BASE_DEC, NULL, 0x00,
3459                 "Optional parameter length",
3460                 HFILL
3461             }
3462         },
3463
3464         /*
3465          * Data Coding Scheme
3466          */
3467         {       &hf_smpp_dcs,
3468                 { "SMPP Data Coding Scheme", "smpp.dcs",
3469                 FT_UINT8, BASE_HEX, VALS(vals_data_coding), 0x00,
3470                 "Data Coding Scheme according to SMPP.",
3471                 HFILL
3472             }
3473         },
3474         {       &hf_smpp_dcs_sms_coding_group,
3475                 {       "DCS Coding Group for SMS", "smpp.dcs.sms_coding_group",
3476                         FT_UINT8, BASE_HEX, VALS(vals_dcs_sms_coding_group), 0xF0,
3477                         "Data Coding Scheme coding group for GSM Short Message Service.",
3478                         HFILL
3479                 }
3480         },
3481         {       &hf_smpp_dcs_text_compression,
3482                 {       "DCS Text compression", "smpp.dcs.text_compression",
3483                         FT_BOOLEAN, 8, TFS(&tfs_dcs_text_compression), 0x20,
3484                         "Indicates if text compression is used.", HFILL
3485                 }
3486         },
3487         {       &hf_smpp_dcs_class_present,
3488                 {       "DCS Class present", "smpp.dcs.class_present",
3489                         FT_BOOLEAN, 8, TFS(&tfs_dcs_class_present), 0x10,
3490                         "Indicates if the message class is present (defined).", HFILL
3491                 }
3492         },
3493         {       &hf_smpp_dcs_charset,
3494                 {       "DCS Character set", "smpp.dcs.charset",
3495                         FT_UINT8, BASE_HEX, VALS(vals_dcs_charset), 0x0C,
3496                         "Specifies the character set used in the message.", HFILL
3497                 }
3498         },
3499         {       &hf_smpp_dcs_class,
3500                 {       "DCS Message class", "smpp.dcs.class",
3501                         FT_UINT8, BASE_HEX, VALS(vals_dcs_class), 0x03,
3502                         "Specifies the message class.", HFILL
3503                 }
3504         },
3505         {       &hf_smpp_dcs_cbs_coding_group,
3506                 {       "DCS Coding Group for CBS", "smpp.dcs.cbs_coding_group",
3507                         FT_UINT8, BASE_HEX, VALS(vals_dcs_cbs_coding_group), 0xF0,
3508                         "Data Coding Scheme coding group for GSM Cell Broadcast Service.",
3509                         HFILL
3510                 }
3511         },
3512         {       &hf_smpp_dcs_cbs_language,
3513                 {       "DCS CBS Message language", "smpp.dcs.cbs_language",
3514                         FT_UINT8, BASE_HEX, VALS(vals_dcs_cbs_language), 0x3F,
3515                         "Language of the GSM Cell Broadcast Service message.", HFILL
3516                 }
3517         },
3518         {       &hf_smpp_dcs_cbs_class,
3519                 {       "DCS CBS Message class", "smpp.dcs.cbs_class",
3520                         FT_UINT8, BASE_HEX, VALS(vals_dcs_cbs_class), 0x03,
3521                         "Specifies the message class for GSM Cell Broadcast Service, for the Data coding / message handling code group.", HFILL
3522                 }
3523         },
3524         {       &hf_smpp_dcs_wap_charset,
3525                 {       "DCS Message coding", "smpp.dcs.wap_coding",
3526                         FT_UINT8, BASE_HEX, VALS(vals_dcs_wap_charset), 0x0C,
3527                         "Specifies the used message encoding, as specified by the WAP Forum (WAP over GSM USSD).", HFILL
3528                 }
3529         },
3530         {       &hf_smpp_dcs_wap_class,
3531                 {       "DCS CBS Message class", "smpp.dcs.wap_class",
3532                         FT_UINT8, BASE_HEX, VALS(vals_dcs_wap_class), 0x03,
3533                         "Specifies the message class for GSM Cell Broadcast Service, as specified by the WAP Forum (WAP over GSM USSD).", HFILL
3534                 }
3535         },
3536         /* Changes in SMPP 5.0 */
3537         {       &hf_smpp_congestion_state,
3538                 {       "Congestion State", "smpp.congestion_state",
3539                         FT_UINT8, BASE_DEC | BASE_RANGE_STRING, RVALS(vals_congestion_state), 0x00,
3540                         "Congestion info between ESME and MC for flow control/cong. control", HFILL
3541                 }
3542         },
3543         {       &hf_smpp_billing_identification,
3544                 {       "Billing Identification", "smpp.billing_id",
3545                         FT_BYTES, BASE_NONE, NULL, 0x00,
3546                         "Billing identification info", HFILL
3547                 }
3548         },
3549         {       &hf_smpp_dest_addr_np_country,
3550                 {       "Destination Country Code", "smpp.dest_addr_np_country",
3551                         FT_BYTES, BASE_NONE, NULL, 0x00,
3552                         "Destination Country Code (E.164 Region Code)", HFILL
3553                 }
3554         },
3555         {       &hf_smpp_dest_addr_np_information,
3556                 {       "Number Portability information", "smpp.dest_addr_np_info",
3557                         FT_BYTES, BASE_NONE, NULL, 0x00,
3558                         NULL, HFILL
3559                 }
3560         },
3561         {       &hf_smpp_dest_addr_np_resolution,
3562                 {       "Number Portability query information", "smpp.dest_addr_np_resolution",
3563                         FT_UINT8, BASE_DEC, VALS(vals_dest_addr_np_resolution), 0x00,
3564                         "Number Portability query information - method used to resolve number", HFILL
3565                 }
3566         },
3567         {       &hf_smpp_source_network_id,
3568                 {       "Source Network ID", "smpp.source_network_id",
3569                         FT_STRING, BASE_NONE, NULL, 0x00,
3570                         "Unique ID for a network or ESME operator", HFILL
3571                 }
3572         },
3573         {       &hf_smpp_source_node_id,
3574                 {       "Source Node ID", "smpp.source_node_id",
3575                         FT_BYTES, BASE_NONE, NULL, 0x00,
3576                         "Unique ID for a ESME or MC node", HFILL
3577                 }
3578         },
3579         {       &hf_smpp_dest_network_id,
3580                 {       "Destination Network ID", "smpp.dest_network_id",
3581                         FT_STRING, BASE_NONE, NULL, 0x00,
3582                         "Unique ID for a network or ESME operator", HFILL
3583                 }
3584         },
3585         {       &hf_smpp_dest_node_id,
3586                 {       "Destination Node ID", "smpp.dest_node_id",
3587                         FT_BYTES, BASE_NONE, NULL, 0x00,
3588                         "Unique ID for a ESME or MC node", HFILL
3589                 }
3590         },
3591         {       &hf_smpp_broadcast_channel_indicator,
3592                 {       "Cell Broadcast channel", "smpp.broadcast_channel_indicator",
3593                         FT_UINT8, BASE_DEC | BASE_RANGE_STRING, RVALS(vals_broadcast_channel_indicator), 0x00,
3594                         NULL, HFILL
3595                 }
3596         },
3597         {       &hf_smpp_broadcast_content_type_nw,
3598                 {       "Broadcast Content Type - Network Tag", "smpp.broadcast_content_type.nw",
3599                         FT_UINT8, BASE_DEC, VALS(vals_broadcast_content_type_nw), 0x00,
3600                         "Cell Broadcast content type", HFILL
3601                 }
3602         },
3603         {       &hf_smpp_broadcast_content_type_type,
3604                 {       "Broadcast Content Type - Content Type", "smpp.broadcast_content_type.type",
3605                         FT_UINT16, BASE_HEX, VALS(vals_broadcast_content_type_type), 0x00,
3606                         "Cell Broadcast content type", HFILL
3607                 }
3608         },
3609         {       &hf_smpp_broadcast_content_type_info,
3610                 {       "Broadcast Content Type Info", "smpp.broadcast_content_type.info",
3611                         FT_BYTES, BASE_NONE, NULL, 0x00,
3612                         "Cell Broadcast content type Info", HFILL
3613                 }
3614         },
3615         {       &hf_smpp_broadcast_message_class,
3616                 {       "Broadcast Message Class", "smpp.broadcast_message_class",
3617                         FT_UINT8, BASE_HEX, VALS(vals_broadcast_message_class), 0x00,
3618                         "Cell Broadcast Message Class", HFILL
3619                 }
3620         },
3621         {       &hf_smpp_broadcast_rep_num,
3622                 {       "Broadcast Message - Number of repetitions requested", "smpp.broadcast_rep_num",
3623                         FT_UINT16, BASE_DEC, NULL, 0x00,
3624                         "Cell Broadcast Message - Number of repetitions requested", HFILL
3625                 }
3626         },
3627         {       &hf_smpp_broadcast_frequency_interval_unit,
3628                 {       "Broadcast Message - frequency interval - Unit", "smpp.broadcast_frequency_interval.unit",
3629                         FT_UINT8, BASE_HEX, VALS(vals_broadcast_frequency_interval_unit), 0x00,
3630                         "Cell Broadcast Message - frequency interval at which broadcast must be repeated", HFILL
3631                 }
3632         },
3633         {       &hf_smpp_broadcast_frequency_interval_value,
3634                 {       "Broadcast Message - frequency interval - Unit", "smpp.broadcast_frequency_interval.value",
3635                         FT_UINT16, BASE_DEC, NULL, 0x00,
3636                         "Cell Broadcast Message - frequency interval at which broadcast must be repeated", HFILL
3637                 }
3638         },
3639         {       &hf_smpp_broadcast_area_identifier,
3640                 {       "Broadcast Message - Area Identifier", "smpp.broadcast_area_identifier",
3641                         FT_BYTES, BASE_NONE, NULL, 0x00,
3642                         "Cell Broadcast Message - Area Identifier", HFILL
3643                 }
3644         },
3645         {       &hf_smpp_broadcast_area_identifier_format,
3646                 {       "Broadcast Message - Area Identifier Format", "smpp.broadcast_area_identifier.format",
3647                         FT_UINT8, BASE_HEX | BASE_RANGE_STRING, RVALS(vals_broadcast_area_identifier_format), 0x00,
3648                         "Cell Broadcast Message - Area Identifier Format", HFILL
3649                 }
3650         },
3651         {       &hf_smpp_broadcast_error_status,
3652                 {       "Broadcast Message - Error Status", "smpp.broadcast_error_status",
3653                         FT_UINT32, BASE_HEX, VALS(vals_command_status), 0x00,
3654                         "Cell Broadcast Message - Error Status", HFILL
3655                 }
3656         },
3657         {       &hf_smpp_broadcast_area_success,
3658                 {       "Broadcast Message - Area Success", "smpp.broadcast_area_success",
3659                         FT_UINT8, BASE_DEC | BASE_RANGE_STRING, RVALS(vals_broadcast_area_success), 0x00,
3660                         "Cell Broadcast Message - success rate indicator (ratio) - No. of BTS which accepted Message:Total BTS", HFILL
3661                 }
3662         },
3663         {       &hf_smpp_broadcast_end_time,
3664                 {       "Broadcast Message - End Time", "smpp.broadcast_end_time",
3665                         FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x00,
3666                         "Cell Broadcast Message - Date and time at which MC set the state of the message to terminated", HFILL
3667                 }
3668         },
3669         {       &hf_smpp_broadcast_end_time_r,
3670                 {       "Broadcast Message - End Time", "smpp.broadcast_end_time_r",
3671                         FT_RELATIVE_TIME, BASE_NONE, NULL, 0x00,
3672                         "Cell Broadcast Message - Date and time at which MC set the state of the message to terminated", HFILL
3673                 }
3674         },
3675         {       &hf_smpp_broadcast_service_group,
3676                 {       "Broadcast Message - Service Group", "smpp.broadcast_service_group",
3677                         FT_BYTES, BASE_NONE, NULL, 0x00,
3678                         "Cell Broadcast Message - Service Group", HFILL
3679                 }
3680         },
3681         /* Huawei SMPP+ extensions */
3682         {    &hf_huawei_smpp_version,
3683                 {       "Version of SMPP+", "smpp.smppplus_version",
3684                         FT_UINT8, BASE_HEX, NULL, 0x00,
3685                         "Indicates the SMPP+ version", HFILL
3686                 }
3687         },
3688         {        &hf_huawei_smpp_smsc_addr,
3689                 {       "SMPP+: GT of SMSC", "smpp.smsc_addr",
3690                         FT_STRING, BASE_NONE, NULL, 0x00,
3691                         "SMPP+: GT of SMSC", HFILL
3692                 }
3693         },
3694         {        &hf_huawei_smpp_msc_addr_noa,
3695                 {       "SMPP+: NOA of MSC address", "smpp.msc_addr_noa",
3696                         FT_UINT8, BASE_DEC, VALS(vals_msc_addr_noa), 0x00,
3697                         "SMPP+: Indicates the TON of MSC address", HFILL
3698                 }
3699         },
3700         {        &hf_huawei_smpp_msc_addr_npi,
3701                 {       "SMPP+: NPI of MSC address", "smpp.msc_addr_npi",
3702                         FT_UINT8, BASE_DEC, VALS(vals_msc_addr_npi), 0x00,
3703                         "SMPP+: Indicates the NPI of MSC address", HFILL
3704                 }
3705         },
3706         {        &hf_huawei_smpp_msc_addr,
3707                 {       "SMPP+: GT of MSC", "smpp.msc_addr",
3708                         FT_STRING, BASE_NONE, NULL, 0x00,
3709                         "SMPP+: GT of MSC", HFILL
3710                 }
3711         },
3712         {        &hf_huawei_smpp_mo_mt_flag,
3713                 {       "SMPP+: Charge for MO or MT", "smpp.mo_mt_flag",
3714                         FT_UINT8, BASE_DEC, VALS(vals_mo_mt_flag), 0x00,
3715                         "SMPP+: Indicates the Charge side of  MO or MT", HFILL
3716                 }
3717         },
3718         {        &hf_huawei_smpp_sm_id,
3719                 {       "SMPP+: Unique SM ID", "smpp.sm_id",
3720                         FT_STRING, BASE_NONE, NULL, 0x00,
3721                         "SMPP+: Unique SM ID which is generated by SMSC", HFILL
3722                 }
3723         },
3724         {        &hf_huawei_smpp_length_auth,
3725                 {       "SMPP+: Length of SMS", "smpp.length_auth",
3726                         FT_UINT32, BASE_DEC, NULL, 0x00,
3727                         "SMPP+: Indicates the Length of SMS", HFILL
3728                 }
3729         },
3730         {        &hf_huawei_smpp_service_id,
3731                 {       "SMPP+: Service ID of SMSC", "smpp.service_id",
3732                         FT_UINT32, BASE_DEC, NULL, 0x00,
3733                         "SMPP+: Indicates the Service ID of SMSC", HFILL
3734                 }
3735         },
3736         {        &hf_huawei_smpp_operation_result,
3737                 {       "SMPP+: Authentication result of SCP", "smpp.operation_result",
3738                         FT_UINT32, BASE_DEC, VALS(vals_operation_result), 0x00,
3739                         "SMPP+: Indicates the Authentication result of SCP", HFILL
3740                 }
3741         },
3742         {        &hf_huawei_smpp_notify_mode,
3743                 {       "SMPP+: SMS notify mode", "smpp.notify_mode",
3744                         FT_UINT8, BASE_DEC, VALS(vals_notify_mode), 0x00,
3745                         "SMPP+: Indicates the SMS notify mode", HFILL
3746                 }
3747         },
3748         {        &hf_huawei_smpp_delivery_result,
3749                 {       "SMPP+: Delivery result of SMS", "smpp.delivery_result",
3750                         FT_UINT32, BASE_DEC, VALS(vals_delivery_result), 0x00,
3751                         "SMPP+: Indicates the Delivery result of SMS", HFILL
3752                 }
3753         }
3754     };
3755
3756     /* Setup protocol subtree array */
3757     static gint *ett[] = {
3758         &ett_smpp,
3759         &ett_dlist,
3760         &ett_dlist_resp,
3761         &ett_opt_params,
3762         &ett_opt_param,
3763         &ett_dcs,
3764     };
3765     DebugLog(("Registering SMPP dissector\n"));
3766     /* Register the protocol name and description */
3767     proto_smpp = proto_register_protocol("Short Message Peer to Peer",
3768                                          "SMPP", "smpp");
3769
3770     /* Required function calls to register header fields and subtrees used */
3771     proto_register_field_array(proto_smpp, hf, array_length(hf));
3772     proto_register_subtree_array(ett, array_length(ett));
3773
3774     /* Allow other dissectors to find this one by name. */
3775     register_dissector("smpp", dissect_smpp, proto_smpp);
3776
3777     /* Register for tapping */
3778     smpp_tap = register_tap("smpp");
3779
3780     /* Preferences */
3781     smpp_module = prefs_register_protocol (proto_smpp, NULL);
3782     prefs_register_bool_preference (smpp_module,
3783             "reassemble_smpp_over_tcp",
3784             "Reassemble SMPP over TCP messages spanning multiple TCP segments",
3785             "Whether the SMPP dissector should reassemble messages spanning multiple TCP segments."
3786             " To use this option, you must also enable "
3787             "\"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
3788             &reassemble_over_tcp);
3789 }
3790
3791 /*
3792  * If dissector uses sub-dissector registration add a registration routine.
3793  * This format is required because a script is used to find these routines and
3794  * create the code that calls these routines.
3795  */
3796 void
3797 proto_reg_handoff_smpp(void)
3798 {
3799     dissector_handle_t smpp_handle;
3800
3801     /*
3802      * SMPP can be spoken on any port under TCP or X.25
3803      * ...how *do* we do that under X.25?
3804      *
3805      * We can register the heuristic SMPP dissector with X.25, for one
3806      * thing.  We don't currently have any mechanism to allow the user
3807      * to specify that a given X.25 circuit is to be dissected as SMPP,
3808      * however.
3809      */
3810     smpp_handle = find_dissector("smpp");
3811     dissector_add_handle("tcp.port", smpp_handle);
3812     heur_dissector_add("tcp", dissect_smpp_heur, proto_smpp);
3813     heur_dissector_add("x.25", dissect_smpp_heur, proto_smpp);
3814
3815     /* Required for call_dissector() */
3816     DebugLog(("Finding gsm-sms-ud subdissector\n"));
3817     gsm_sms_handle = find_dissector("gsm-sms-ud");
3818     DISSECTOR_ASSERT(gsm_sms_handle);
3819
3820     /* Tapping setup */
3821     stats_tree_register_with_group("smpp","smpp_commands", "SM_PP Operations", 0,
3822                                    smpp_stats_tree_per_packet, smpp_stats_tree_init,
3823                                    NULL, REGISTER_STAT_GROUP_TELEPHONY);
3824 }