MSWSP: fix dissect_mswsp_smb()
[wireshark-wip.git] / epan / dissectors / packet-gmr1_rach.c
blob08507a68fe3c4d22d692f50974b0a8f1bbdba209
1 /* packet-gmr1_rach.c
3 * Routines for GMR-1 RACH dissection in wireshark.
4 * Copyright (c) 2012 Sylvain Munaut <tnt@246tNt.com>
6 * References:
7 * [1] ETSI TS 101 376-4-8 V1.3.1 - GMR-1 04.008
8 * [2] ETSI TS 101 376-4-8 V2.2.1 - GMPRS-1 04.008
9 * [3] ETSI TS 101 376-4-8 V3.1.1 - GMR-1 3G 44.008
11 * Especially [1] 10.1.8
13 * $Id$
15 * Wireshark - Network traffic analyzer
16 * By Gerald Combs <gerald@wireshark.org>
17 * Copyright 1998 Gerald Combs
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License
21 * as published by the Free Software Foundation; either version 2
22 * of the License, or (at your option) any later version.
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
34 #include "config.h"
36 #include <glib.h>
38 #include <stdlib.h>
40 #include <epan/packet.h>
42 #include "packet-csn1.h"
45 /* GMR-1 RACH proto */
46 static int proto_gmr1_rach = -1;
48 /* GMR-1 RACH subtrees */
49 static gint ett_rach_msg = -1;
50 static gint ett_rach_kls1 = -1;
51 static gint ett_rach_kls2 = -1;
52 static gint ett_rach_est_cause = -1;
53 static gint ett_rach_dialed_num = -1;
54 static gint ett_rach_gps_pos = -1;
56 /* Handoffs */
57 static dissector_handle_t data_handle;
59 /* Fields */
60 static int hf_rach_prio = -1;
61 static int hf_rach_est_cause = -1;
62 static int hf_rach_est_cause_moc = -1;
63 static int hf_rach_est_cause_pag_resp = -1;
64 static int hf_rach_num_plan = -1;
65 static int hf_rach_chan_needed = -1;
66 static int hf_rach_retry_cnt = -1;
67 static int hf_rach_precorr = -1;
68 static int hf_rach_rand_ref = -1;
70 static int hf_rach_gps_pos_cpi = -1;
71 static int hf_rach_gps_pos_lat = -1;
72 static int hf_rach_gps_pos_long = -1;
74 static int hf_rach_mes_pwr_class = -1;
75 static int hf_rach_sp_hplmn_id = -1;
76 static int hf_rach_pd = -1;
77 static int hf_rach_number = -1;
78 static int hf_rach_number_grp1 = -1;
79 static int hf_rach_number_grp2 = -1;
80 static int hf_rach_number_grp3 = -1;
81 static int hf_rach_number_grp4 = -1;
82 static int hf_rach_number_grp5 = -1;
83 static int hf_rach_msc_id = -1;
84 static int hf_rach_gps_timestamp = -1;
85 static int hf_rach_software_version = -1;
86 static int hf_rach_spare = -1;
87 static int hf_rach_gci = -1;
88 static int hf_rach_r = -1;
89 static int hf_rach_o = -1;
90 static int hf_rach_number_type = -1;
93 static const value_string rach_prio_vals[] = {
94 { 0, "Normal Call" },
95 { 1, "Priority Call" },
96 { 0, NULL }
99 static const value_string rach_est_cause_vals[] = {
100 { 4, "In response to alerting" },
101 { 8, "Location update" },
102 { 9, "IMSI Detach" },
103 { 10, "Supplementary Services" },
104 { 11, "Short Message Services" },
105 { 12, "Position Verification" },
106 { 15, "Emergency Call" },
107 { 0, NULL }
110 static const value_string rach_est_cause_moc_vals[] = {
111 { 1, "Mobile Originated Call" },
112 { 0, NULL }
115 static const value_string rach_est_cause_pag_resp_vals[] = {
116 { 0, "In response to paging" },
117 { 0, NULL }
120 static const value_string rach_num_plan_vals[] = {
121 { 0, "Unknown" },
122 { 1, "ISDN E.164/E.163" },
123 { 2, "Not Used" },
124 { 3, "X.121" },
125 { 4, "Telex F.69" },
126 { 8, "National Numbering Plan" },
127 { 9, "Private Numbering Plan" },
128 { 15, "Reserved for Extension" },
129 { 0, NULL }
132 static const value_string rach_chan_needed_vals[] = {
133 { 0, "any" },
134 { 1, "SDCCH" },
135 { 2, "TCH3" },
136 { 3, "spare" },
137 { 0, NULL }
140 static const value_string rach_precorr_vals[] = {
141 { 0, "Reserved" },
142 { 1, "-47 symbols correction" },
143 { 2, "-94 symbols correction" },
144 { 3, "-141 symbols correction" },
145 { 4, "+141 symbols correction" },
146 { 5, "+94 symbols correction" },
147 { 6, "+47 symbols correction" },
148 { 7, "No precorrection" },
149 { 0, NULL }
152 static void
153 dissect_gmr1_rach_kls1(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
154 int *is_moc)
156 proto_item *ec_item = NULL;
157 proto_tree *ec_tree = NULL;
158 guint8 ec;
160 /* Priority */
161 proto_tree_add_item(tree, hf_rach_prio,
162 tvb, offset, 1, ENC_BIG_ENDIAN);
164 /* Establishment Cause */
165 ec = (tvb_get_guint8(tvb, offset) >> 1) & 0x1f;
167 *is_moc = !!(ec & 0x10);
169 if (ec & 0x10)
171 /* MOC */
172 ec_item = proto_tree_add_item(tree, hf_rach_est_cause_moc,
173 tvb, offset, 1, ENC_BIG_ENDIAN);
175 ec_tree = proto_item_add_subtree(ec_item, ett_rach_est_cause);
177 col_append_str(pinfo->cinfo, COL_INFO, "Mobile Originated Call ");
179 /* Numbering plan */
180 proto_tree_add_item(ec_tree, hf_rach_num_plan,
181 tvb, offset, 1, ENC_BIG_ENDIAN);
183 else if ((ec & 0x1c) == 0x00)
185 /* Paging response */
186 ec_item = proto_tree_add_item(tree, hf_rach_est_cause_pag_resp,
187 tvb, offset, 1, ENC_BIG_ENDIAN);
189 ec_tree = proto_item_add_subtree(ec_item, ett_rach_est_cause);
191 col_append_str(pinfo->cinfo, COL_INFO, "Paging response ");
193 /* Channel Needed */
194 proto_tree_add_item(ec_tree, hf_rach_chan_needed,
195 tvb, offset, 1, ENC_BIG_ENDIAN);
197 else
199 proto_tree_add_item(tree, hf_rach_est_cause,
200 tvb, offset, 1, ENC_BIG_ENDIAN);
202 col_append_fstr(pinfo->cinfo, COL_INFO, "%s",
203 val_to_str(ec, rach_est_cause_vals, "Unknown (%u)"));
206 /* Retry counter */
207 proto_tree_add_item(tree, hf_rach_retry_cnt,
208 tvb, offset, 1, ENC_BIG_ENDIAN);
210 /* Precorrection Indication */
211 proto_tree_add_item(tree, hf_rach_precorr,
212 tvb, offset + 1, 1, ENC_BIG_ENDIAN);
214 /* Random Reference */
215 proto_tree_add_item(tree, hf_rach_rand_ref,
216 tvb, offset + 1, 1, ENC_BIG_ENDIAN);
220 static const value_string rach_gps_pos_cpi_vals[] = {
221 { 0, "GPS position is old position" },
222 { 1, "GPS position is current position" },
223 { 0, NULL }
226 static void
227 rach_gps_pos_lat_fmt(gchar *s, guint32 v)
229 gint32 sv;
231 if (v & (1<<18))
232 v |= 0xfff80000;
234 sv = v;
236 g_snprintf(s, ITEM_LABEL_LENGTH, "%.5f %s (%d)",
237 abs(sv) / 2912.7f, sv < 0 ? "S" : "N", sv);
240 static void
241 rach_gps_pos_long_fmt(gchar *s, guint32 v)
243 gint32 sv;
245 if (v & (1<<19))
246 v |= 0xfff00000;
248 sv = v;
250 g_snprintf(s, ITEM_LABEL_LENGTH, "%.5f %s (%d)",
251 abs(sv) / 2912.70555f, sv < 0 ? "W" : "E", sv);
253 /* FIXME: The specs says >0 is West ... but it doesn't seem to
254 * match real world captures !
258 static void
259 dissect_gmr1_rach_gps_pos(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
261 guint32 lat;
263 /* Check for NULL */
264 lat = (tvb_get_ntohl(tvb, offset) >> 4) & 0x7ffff;
265 if (lat == 0x40000) {
266 proto_tree_add_text(tree, tvb, offset, 5, "NULL GPS Position");
267 return;
270 /* CPI */
271 proto_tree_add_item(tree, hf_rach_gps_pos_cpi,
272 tvb, offset, 1, ENC_BIG_ENDIAN);
274 /* Latitude */
275 proto_tree_add_item(tree, hf_rach_gps_pos_lat,
276 tvb, offset, 3, ENC_BIG_ENDIAN);
278 /* Longitude */
279 proto_tree_add_item(tree, hf_rach_gps_pos_long,
280 tvb, offset + 2, 3, ENC_BIG_ENDIAN);
284 static void
285 rach_sp_hplmn_id_fmt(gchar *s, guint32 v)
287 if (v == 0xfffff) {
288 g_snprintf(s, ITEM_LABEL_LENGTH, "%05x (Null)", v);
289 } else if ((v & 0xf8000) == 0xf8000) {
290 g_snprintf(s, ITEM_LABEL_LENGTH, "%05x (SP ID %4d)", v, v & 0x7fff);
291 } else {
292 g_snprintf(s, ITEM_LABEL_LENGTH, "%05x (HPLMN ID)", v);
296 static const value_string rach_pd_vals[] = {
297 { 0, "Fixed to 00 for this version of the protocol" },
298 { 1, "Reserved" },
299 { 2, "Reserved" },
300 { 3, "Reserved" },
301 { 0, NULL }
304 static void
305 rach_dialed_num_grp1234_fmt(gchar *s, guint32 v)
307 g_snprintf(s, ITEM_LABEL_LENGTH, "%03d", v);
310 static void
311 rach_dialed_num_grp5_fmt(gchar *s, guint32 v)
313 if (v <= 999) {
314 g_snprintf(s, ITEM_LABEL_LENGTH, "%03d", v);
315 } else if (v == 1023) {
316 g_snprintf(s, ITEM_LABEL_LENGTH,
317 "All digits in the preceding group are valid (%d)", v);
318 } else if (v == 1022) {
319 g_snprintf(s, ITEM_LABEL_LENGTH,
320 "First two digits in the preceding group are valid, "
321 "and the third digit (i.e. 0) is padding(%d)", v);
322 } else if (v == 1021) {
323 g_snprintf(s, ITEM_LABEL_LENGTH,
324 "First digit in the preceding group is valid, and "
325 "the second and third 0s are padding(%d)", v);
326 } else if (v >= 1100 && v <= 1199) {
327 g_snprintf(s, ITEM_LABEL_LENGTH, "%02d (%d)", v - 1100, v);
328 } else if (v >= 1200 && v <= 1209) {
329 g_snprintf(s, ITEM_LABEL_LENGTH, "%01d (%d)", v - 1200, v);
330 } else {
331 g_snprintf(s, ITEM_LABEL_LENGTH, "Invalid (%d)", v);
335 static void
336 rach_gps_timestamp_fmt(gchar *s, guint32 v)
338 if (v == 0xffff) {
339 g_snprintf(s, ITEM_LABEL_LENGTH, ">= 65535 minutes or N/A (%04x)", v);
340 } else {
341 g_snprintf(s, ITEM_LABEL_LENGTH, "%d minutes (%04x)", v, v);
345 static const value_string rach_gci_vals[] = {
346 { 0, "MES is not GPS capable" },
347 { 1, "MES is GPS capable" },
348 { 0, NULL }
351 static const value_string rach_number_type_vals[] = {
352 { 0, "Unknown" },
353 { 1, "International Number" },
354 { 2, "National Number" },
355 { 3, "Network-specific Number (operator access)" },
356 { 4, "Dedicated Access short code" },
357 { 5, "Reserved" },
358 { 6, "Reserved" },
359 { 7, "(N/A - Not MO Call)" },
360 { 0, NULL }
363 static int
364 _parse_dialed_number(gchar *s, int slen, tvbuff_t *tvb, int offset)
366 guint16 grp[5];
367 int rv;
369 grp[0] = ((tvb_get_guint8(tvb, offset+0) & 0x3f) << 4) |
370 ((tvb_get_guint8(tvb, offset+1) & 0xf0) >> 4);
371 grp[1] = ((tvb_get_guint8(tvb, offset+1) & 0x0f) << 6) |
372 ((tvb_get_guint8(tvb, offset+2) & 0xfc) >> 2);
373 grp[2] = ((tvb_get_guint8(tvb, offset+2) & 0x03) << 8) |
374 tvb_get_guint8(tvb, offset+3);
375 grp[3] = ((tvb_get_guint8(tvb, offset+4) & 0xff) << 2) |
376 ((tvb_get_guint8(tvb, offset+5) & 0xc0) >> 6);
377 grp[4] = ((tvb_get_guint8(tvb, offset+5) & 0x3f) << 5) |
378 ((tvb_get_guint8(tvb, offset+6) & 0xf8) >> 3);
380 rv = g_snprintf(s, slen, "%03d%03d%03d", grp[0], grp[1], grp[2]);
382 if (grp[4] <= 999) {
383 rv += g_snprintf(s + rv, ITEM_LABEL_LENGTH,
384 "%03d%03d", grp[3], grp[4]);
385 } else if (grp[4] == 1023) {
386 rv += g_snprintf(s + rv, ITEM_LABEL_LENGTH,
387 "%03d", grp[3]);
388 } else if (grp[4] == 1022) {
389 rv += g_snprintf(s + rv, ITEM_LABEL_LENGTH,
390 "%02d", grp[3] / 10);
391 } else if (grp[4] == 1021) {
392 rv += g_snprintf(s + rv, ITEM_LABEL_LENGTH,
393 "%01d", grp[3] / 100);
394 } else if (grp[4] >= 1100 && grp[4] <= 1199) {
395 rv += g_snprintf(s + rv, ITEM_LABEL_LENGTH,
396 "%03d%02d", grp[3], grp[4] - 1100);
397 } else if (grp[4] >= 1200 && grp[4] <= 1209) {
398 rv += g_snprintf(s + rv, ITEM_LABEL_LENGTH,
399 "%03d%01d", grp[3], grp[4] - 1200);
400 } else {
401 rv += g_snprintf(s + rv, ITEM_LABEL_LENGTH,
402 "%03d%03d (Invalid)", grp[3], grp[4]);
405 return rv;
408 static void
409 dissect_gmr1_rach_kls2(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
410 int is_moc)
412 proto_item *dialed_num_item = NULL, *gps_pos_item = NULL;
413 proto_tree *dialed_num_tree = NULL, *gps_pos_tree = NULL;
415 /* MES Power Class */
416 proto_tree_add_item(tree, hf_rach_mes_pwr_class,
417 tvb, offset, 1, ENC_BIG_ENDIAN);
419 /* SP/HPLMN ID */
420 proto_tree_add_item(tree, hf_rach_sp_hplmn_id,
421 tvb, offset, 3, ENC_BIG_ENDIAN);
423 /* PD */
424 proto_tree_add_item(tree, hf_rach_pd,
425 tvb, offset + 3, 1, ENC_BIG_ENDIAN);
428 /* Is it a MO call ? */
429 if (is_moc) {
430 gchar s[32];
432 /* Dialed number */
433 /* Parse number */
434 _parse_dialed_number(s, sizeof(s), tvb, offset + 3);
436 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", s);
438 /* Base item */
439 dialed_num_item = proto_tree_add_string(
440 tree, hf_rach_number, tvb, offset + 3, 7, s);
442 dialed_num_tree = proto_item_add_subtree(
443 dialed_num_item, ett_rach_dialed_num);
445 /* Group 1 */
446 proto_tree_add_item(dialed_num_tree, hf_rach_number_grp1,
447 tvb, offset + 3, 2, ENC_BIG_ENDIAN);
449 /* Group 2 */
450 proto_tree_add_item(dialed_num_tree, hf_rach_number_grp2,
451 tvb, offset + 4, 2, ENC_BIG_ENDIAN);
453 /* Group 3 */
454 proto_tree_add_item(dialed_num_tree, hf_rach_number_grp3,
455 tvb, offset + 5, 2, ENC_BIG_ENDIAN);
457 /* Group 4 */
458 proto_tree_add_item(dialed_num_tree, hf_rach_number_grp4,
459 tvb, offset + 7, 2, ENC_BIG_ENDIAN);
461 /* Group 5 */
462 proto_tree_add_item(dialed_num_tree, hf_rach_number_grp5,
463 tvb, offset + 8, 2, ENC_BIG_ENDIAN);
464 } else {
465 /* MSC ID */
466 proto_tree_add_item(tree, hf_rach_msc_id,
467 tvb, offset + 3, 1, ENC_BIG_ENDIAN);
469 /* GPS timestamp */
470 proto_tree_add_item(tree, hf_rach_gps_timestamp,
471 tvb, offset + 4, 2, ENC_BIG_ENDIAN);
473 /* Software version number */
474 proto_tree_add_item(tree, hf_rach_software_version,
475 tvb, offset + 6, 1, ENC_BIG_ENDIAN);
477 /* Spare */
478 proto_tree_add_item(tree, hf_rach_spare,
479 tvb, offset + 6, 1, ENC_BIG_ENDIAN);
482 /* GCI */
483 proto_tree_add_item(tree, hf_rach_gci,
484 tvb, offset + 9, 1, ENC_BIG_ENDIAN);
486 /* R */
487 proto_tree_add_item(tree, hf_rach_r,
488 tvb, offset + 9, 1, ENC_BIG_ENDIAN);
490 /* O */
491 proto_tree_add_item(tree, hf_rach_o,
492 tvb, offset + 9, 1, ENC_BIG_ENDIAN);
494 /* GPS Position */
495 gps_pos_item = proto_tree_add_text(
496 tree, tvb, offset + 10, 5,
497 "GPS Position");
498 gps_pos_tree = proto_item_add_subtree(gps_pos_item, ett_rach_gps_pos);
500 dissect_gmr1_rach_gps_pos(tvb, offset + 10, pinfo, gps_pos_tree);
502 /* Number type */
503 proto_tree_add_item(tree, hf_rach_number_type,
504 tvb, offset + 15, 1, ENC_BIG_ENDIAN);
508 static void
509 dissect_gmr1_rach(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
511 proto_item *rach_item = NULL, *kls1_item = NULL, *kls2_item = NULL;
512 proto_tree *rach_tree = NULL, *kls1_tree = NULL, *kls2_tree = NULL;
513 int len, is_moc;
515 len = tvb_length(tvb);
517 rach_item = proto_tree_add_protocol_format(
518 tree, proto_gmr1_rach, tvb, 0, len,
519 "GMR-1 Channel Request (RACH)");
520 rach_tree = proto_item_add_subtree(rach_item, ett_rach_msg);
522 if (len != 18) {
523 col_append_str(pinfo->cinfo, COL_INFO, "(Invalid)");
524 call_dissector(data_handle, tvb, pinfo, tree);
525 return;
528 col_append_str(pinfo->cinfo, COL_INFO, "(RACH) ");
530 kls1_item = proto_tree_add_text(
531 rach_tree, tvb, 0, 2,
532 "Class-1 informations");
533 kls1_tree = proto_item_add_subtree(kls1_item, ett_rach_kls1);
535 dissect_gmr1_rach_kls1(tvb, 0, pinfo, kls1_tree, &is_moc);
537 kls2_item = proto_tree_add_text(
538 rach_tree, tvb, 2, 16,
539 "Class-2 informations");
540 kls2_tree = proto_item_add_subtree(kls2_item, ett_rach_kls2);
542 dissect_gmr1_rach_kls2(tvb, 2, pinfo, kls2_tree, is_moc);
545 void
546 proto_register_gmr1_rach(void)
548 static hf_register_info hf[] = {
549 { &hf_rach_prio,
550 { "Priority", "gmr1.rach.priority",
551 FT_UINT8, BASE_DEC, VALS(rach_prio_vals), 0x01,
552 NULL, HFILL }
554 { &hf_rach_est_cause,
555 { "Establishment Cause", "gmr1.rach.est_cause",
556 FT_UINT8, BASE_HEX, VALS(rach_est_cause_vals), 0x3e,
557 NULL, HFILL }
559 { &hf_rach_est_cause_moc,
560 { "Establishment Cause", "gmr1.rach.est_cause.moc",
561 FT_UINT8, BASE_HEX, VALS(rach_est_cause_moc_vals), 0x20,
562 NULL, HFILL }
564 { &hf_rach_est_cause_pag_resp,
565 { "Establishment Cause", "gmr1.rach.est_cause.pag_resp",
566 FT_UINT8, BASE_HEX, VALS(rach_est_cause_pag_resp_vals), 0x38,
567 NULL, HFILL }
569 { &hf_rach_num_plan,
570 { "Numbering Plan Identification", "gmr1.rach.numbering_plan",
571 FT_UINT8, BASE_DEC, VALS(rach_num_plan_vals), 0x1e,
572 NULL, HFILL }
574 { &hf_rach_chan_needed,
575 { "Channel Needed", "gmr1.rach.chan_needed",
576 FT_UINT8, BASE_DEC, VALS(rach_chan_needed_vals), 0x06,
577 "Echoed from Paging Request", HFILL }
579 { &hf_rach_retry_cnt,
580 { "Retry Counter", "gmr1.rach.retry_counter",
581 FT_UINT8, BASE_DEC, NULL, 0xc0,
582 "Retransmission count for current access attempt", HFILL }
584 { &hf_rach_precorr,
585 { "Precorrection Indication", "gmr1.rach.precorr_ind",
586 FT_UINT8, BASE_DEC, VALS(rach_precorr_vals), 0xe0,
587 "This is the timing correction applied to RACH while "
588 "sending this message. See GMR 05.010.", HFILL }
590 { &hf_rach_rand_ref,
591 { "Random Reference", "gmr1.rach.random_reference",
592 FT_UINT8, BASE_HEX, NULL, 0x1f,
593 "A random number of 5 bits", HFILL }
595 { &hf_rach_gps_pos_cpi,
596 { "CPI", "gmr1.rach.gps_pos.cpi",
597 FT_UINT8, BASE_DEC, VALS(rach_gps_pos_cpi_vals), 0x80,
598 "Current Position Indicator", HFILL }
600 { &hf_rach_gps_pos_lat,
601 { "Latitude", "gmr1.rach.gps_pos.latitude",
602 FT_UINT24, BASE_CUSTOM, rach_gps_pos_lat_fmt, 0x7ffff0,
603 NULL, HFILL }
605 { &hf_rach_gps_pos_long,
606 { "Longitude", "gmr1.rach.gps_pos.longitude",
607 FT_UINT24, BASE_CUSTOM, rach_gps_pos_long_fmt, 0x0fffff,
608 NULL, HFILL }
610 { &hf_rach_mes_pwr_class,
611 { "MES Power Class", "gmr1.rach.mes_power_class",
612 FT_UINT8, BASE_DEC, NULL, 0xf0,
613 "See GMR 05.005 for infos", HFILL }
615 { &hf_rach_sp_hplmn_id,
616 { "SP/HPLMN ID", "gmr1.rach.sp_hplmn_id",
617 FT_UINT24, BASE_CUSTOM, rach_sp_hplmn_id_fmt, 0x0fffff,
618 NULL, HFILL }
620 { &hf_rach_pd,
621 { "PD", "gmr1.rach.pd",
622 FT_UINT8, BASE_DEC, VALS(rach_pd_vals), 0xc0,
623 "Protocol Discriminator", HFILL }
625 { &hf_rach_number,
626 { "Dialed Number", "gmr1.rach.number",
627 FT_STRING, BASE_NONE, NULL, 0x00,
628 NULL, HFILL }
630 { &hf_rach_number_grp1,
631 { "Group 1", "gmr1.rach.number.grp1",
632 FT_UINT16, BASE_CUSTOM, rach_dialed_num_grp1234_fmt, 0x3ff0,
633 NULL, HFILL }
635 { &hf_rach_number_grp2,
636 { "Group 2", "gmr1.rach.number.grp2",
637 FT_UINT16, BASE_CUSTOM, rach_dialed_num_grp1234_fmt, 0x0ffc,
638 NULL, HFILL }
640 { &hf_rach_number_grp3,
641 { "Group 3", "gmr1.rach.number.grp3",
642 FT_UINT16, BASE_CUSTOM, rach_dialed_num_grp1234_fmt, 0x03ff,
643 NULL, HFILL }
645 { &hf_rach_number_grp4,
646 { "Group 4", "gmr1.rach.number.grp4",
647 FT_UINT16, BASE_CUSTOM, rach_dialed_num_grp1234_fmt, 0xffc0,
648 NULL, HFILL }
650 { &hf_rach_number_grp5,
651 { "Group 5", "gmr1.rach.number.grp5",
652 FT_UINT16, BASE_CUSTOM, rach_dialed_num_grp5_fmt, 0x3ff8,
653 NULL, HFILL }
655 { &hf_rach_msc_id,
656 { "MSC ID", "gmr1.rach.msc_id",
657 FT_UINT8, BASE_DEC, NULL, 0x3f,
658 NULL, HFILL }
660 { &hf_rach_gps_timestamp,
661 { "GPS Timestamp", "gmr1.rach.gps_timestamp",
662 FT_UINT16, BASE_CUSTOM, rach_gps_timestamp_fmt, 0xffff,
663 NULL, HFILL }
665 { &hf_rach_software_version,
666 { "Software Version", "gmr1.rach.software_version",
667 FT_UINT8, BASE_DEC, NULL, 0xfe,
668 NULL, HFILL }
670 { &hf_rach_spare,
671 { "Spare", "gmr1.rach.spare",
672 FT_UINT32, BASE_DEC, NULL, 0x01fffff8,
673 NULL, HFILL }
675 { &hf_rach_gci,
676 { "GCI", "gmr1.rach.gci",
677 FT_UINT8, BASE_DEC, VALS(rach_gci_vals), 0x01,
678 "GPS Capability Indicator", HFILL }
680 { &hf_rach_r,
681 { "R", "gmr1.rach.r",
682 FT_UINT8, BASE_DEC, NULL, 0x02,
683 "See GMR 04.008 10.1.8 for full description" , HFILL }
685 { &hf_rach_o,
686 { "O", "gmr1.rach.o",
687 FT_UINT8, BASE_DEC, NULL, 0x04,
688 "See GMR 04.008 10.1.8 for full description", HFILL }
690 { &hf_rach_number_type,
691 { "Number Type", "gmr1.rach.number_type",
692 FT_UINT8, BASE_DEC, VALS(rach_number_type_vals), 0x07,
693 "For MO Call only", HFILL }
697 static gint *ett[] = {
698 &ett_rach_msg,
699 &ett_rach_kls1,
700 &ett_rach_kls2,
701 &ett_rach_est_cause,
702 &ett_rach_dialed_num,
703 &ett_rach_gps_pos,
706 proto_gmr1_rach = proto_register_protocol("GEO-Mobile Radio (1) RACH", "GMR-1 RACH", "gmr1.rach");
708 proto_register_field_array(proto_gmr1_rach, hf, array_length(hf));
709 proto_register_subtree_array(ett, array_length(ett));
711 register_dissector("gmr1_rach", dissect_gmr1_rach, proto_gmr1_rach);
714 void
715 proto_reg_handoff_gmr1_rach(void)
717 data_handle = find_dissector("data");