Coverage Report

Created: 2022-06-17 11:01

/src/wireshark/epan/dissectors/packet-gmr1_rach.c
Line
Count
Source (jump to first uncovered line)
1
/* packet-gmr1_rach.c
2
 *
3
 * Routines for GMR-1 RACH dissection in wireshark.
4
 * Copyright (c) 2012 Sylvain Munaut <tnt@246tNt.com>
5
 *
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
10
 *
11
 * Especially [1] 10.1.8
12
 *
13
 * Wireshark - Network traffic analyzer
14
 * By Gerald Combs <gerald@wireshark.org>
15
 * Copyright 1998 Gerald Combs
16
 *
17
 * SPDX-License-Identifier: GPL-2.0-or-later
18
 */
19
20
#include "config.h"
21
22
#include <stdlib.h>
23
24
#include <epan/packet.h>
25
26
27
void proto_register_gmr1_rach(void);
28
29
/* GMR-1 RACH proto */
30
static int proto_gmr1_rach = -1;
31
32
/* GMR-1 RACH subtrees */
33
static gint ett_rach_msg = -1;
34
static gint ett_rach_kls1 = -1;
35
static gint ett_rach_kls2 = -1;
36
static gint ett_rach_gmprs_type1_kls2 = -1;
37
static gint ett_rach_gmprs_type2_kls2 = -1;
38
static gint ett_rach_est_cause = -1;
39
static gint ett_rach_dialed_num = -1;
40
static gint ett_rach_gps_pos = -1;
41
static gint ett_rach_gmprs_req_type = -1;
42
43
/* Fields */
44
static int hf_rach_prio = -1;
45
static int hf_rach_est_cause = -1;
46
static int hf_rach_est_cause_moc = -1;
47
static int hf_rach_est_cause_pag_resp = -1;
48
static int hf_rach_num_plan = -1;
49
static int hf_rach_chan_needed = -1;
50
static int hf_rach_retry_cnt = -1;
51
static int hf_rach_precorr = -1;
52
static int hf_rach_rand_ref = -1;
53
54
static int hf_rach_gps_pos_cpi = -1;
55
static int hf_rach_gps_pos_lat = -1;
56
static int hf_rach_gps_pos_long = -1;
57
58
static int hf_rach_mes_pwr_class = -1;
59
static int hf_rach_sp_hplmn_id = -1;
60
static int hf_rach_pd = -1;
61
static int hf_rach_number = -1;
62
static int hf_rach_number_grp1 = -1;
63
static int hf_rach_number_grp2 = -1;
64
static int hf_rach_number_grp3 = -1;
65
static int hf_rach_number_grp4 = -1;
66
static int hf_rach_number_grp5 = -1;
67
static int hf_rach_msc_id = -1;
68
static int hf_rach_gps_timestamp = -1;
69
static int hf_rach_software_version = -1;
70
static int hf_rach_spare = -1;
71
static int hf_rach_gci = -1;
72
static int hf_rach_r = -1;
73
static int hf_rach_o = -1;
74
static int hf_rach_number_type = -1;
75
76
static int hf_rach_gmprs_term_type = -1;
77
static int hf_rach_gmprs_radio_prio = -1;
78
static int hf_rach_gmprs_tlli = -1;
79
static int hf_rach_gmprs_num_rlc_blks = -1;
80
static int hf_rach_gmprs_peak_tput = -1;
81
static int hf_rach_gmprs_dl_peak_tput = -1;
82
static int hf_rach_gmprs_ul_peak_tput = -1;
83
static int hf_rach_gmprs_rlc_mode = -1;
84
static int hf_rach_gmprs_llc_mode = -1;
85
static int hf_rach_gmprs_spare1 = -1;
86
static int hf_rach_gmprs_spare2 = -1;
87
static int hf_rach_gmprs_spare3 = -1;
88
static int hf_rach_gmprs_reserved1 = -1;
89
static int hf_rach_gmprs_req_type = -1;
90
static int hf_rach_gmprs_req_type_pag_resp = -1;
91
static int hf_rach_gmprs_chan_needed = -1;
92
93
94
static const true_false_string rach_prio_tfs = {
95
  "Priority Call",
96
  "Normal Call"
97
};
98
99
static const value_string rach_est_cause_vals[] = {
100
  {  4, "In response to alerting" },
101
  {  7, "(GmPRS) Channel Request Type 2" },
102
  {  8, "Location update" },
103
  {  9, "IMSI Detach" },
104
  { 10, "Supplementary Services" },
105
  { 11, "Short Message Services" },
106
  { 12, "Position Verification" },
107
  { 13, "(GmPRS) Attach/RA Update" },
108
  { 14, "(GmPRS) Packet Data Transfer" },
109
  { 15, "Emergency Call" },
110
  { 0, NULL }
111
};
112
113
static const value_string rach_est_cause_moc_vals[] = {
114
  { 1, "Mobile Originated Call" },
115
  { 0, NULL }
116
};
117
118
static const value_string rach_est_cause_pag_resp_vals[] = {
119
  { 0, "In response to paging" },
120
  { 0, NULL }
121
};
122
123
static const value_string rach_num_plan_vals[] = {
124
  {  0, "Unknown" },
125
  {  1, "ISDN E.164/E.163" },
126
  {  2, "Not Used" },
127
  {  3, "X.121" },
128
  {  4, "Telex F.69" },
129
  {  8, "National Numbering Plan" },
130
  {  9, "Private Numbering Plan" },
131
  { 15, "Reserved for Extension" },
132
  { 0, NULL }
133
};
134
135
static const value_string rach_chan_needed_vals[] = {
136
  { 0, "any" },
137
  { 1, "SDCCH" },
138
  { 2, "TCH3" },
139
  { 3, "spare" },
140
  { 0, NULL }
141
};
142
143
static const value_string rach_precorr_vals[] = {
144
  { 0, "Reserved" },
145
  { 1, "-47 symbols correction" },
146
  { 2, "-94 symbols correction" },
147
  { 3, "-141 symbols correction" },
148
  { 4, "+141 symbols correction" },
149
  { 5, "+94 symbols correction" },
150
  { 6, "+47 symbols correction" },
151
  { 7, "No precorrection" },
152
  { 0, NULL }
153
};
154
155
static void
156
dissect_gmr1_rach_kls1(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *root_tree,
157
           int *is_moc, int *is_pdt)
158
0
{
159
0
  proto_tree *tree = NULL;
160
0
  proto_item *ec_item = NULL;
161
0
  proto_tree *ec_tree = NULL;
162
0
  guint8 ec;
163
164
  /* Tree */
165
0
  tree = proto_tree_add_subtree(
166
0
    root_tree, tvb, 0, 2,
167
0
    ett_rach_kls1, NULL, "Class-1 informations");
168
169
  /* Priority */
170
0
  proto_tree_add_item(tree, hf_rach_prio,
171
0
                      tvb, offset, 1, ENC_BIG_ENDIAN);
172
173
  /* Establishment Cause */
174
0
  ec = (tvb_get_guint8(tvb, offset) >> 1) & 0x1f;
175
176
0
  *is_moc = !!(ec & 0x10);
177
0
  *is_pdt = (ec == 14);
178
179
0
  if (ec & 0x10)
180
0
  {
181
    /* MOC */
182
0
    ec_item = proto_tree_add_item(tree, hf_rach_est_cause_moc,
183
0
                                  tvb, offset, 1, ENC_BIG_ENDIAN);
184
185
0
    ec_tree = proto_item_add_subtree(ec_item, ett_rach_est_cause);
186
187
0
    col_append_str(pinfo->cinfo, COL_INFO, "Mobile Originated Call ");
188
189
    /* Numbering plan */
190
0
    proto_tree_add_item(ec_tree, hf_rach_num_plan,
191
0
                        tvb, offset, 1, ENC_BIG_ENDIAN);
192
0
  }
193
0
  else if ((ec & 0x1c) == 0x00)
194
0
  {
195
    /* Paging response */
196
0
    ec_item = proto_tree_add_item(tree, hf_rach_est_cause_pag_resp,
197
0
                                  tvb, offset, 1, ENC_BIG_ENDIAN);
198
199
0
    ec_tree = proto_item_add_subtree(ec_item, ett_rach_est_cause);
200
201
0
    col_append_str(pinfo->cinfo, COL_INFO, "Paging response ");
202
203
    /* Channel Needed */
204
0
    proto_tree_add_item(ec_tree, hf_rach_chan_needed,
205
0
                        tvb, offset, 1, ENC_BIG_ENDIAN);
206
0
  }
207
0
  else if (ec == 7)
208
0
  {
209
    /* Channel Request Type 2 */
210
0
    proto_tree_add_item(tree, hf_rach_est_cause,
211
0
                        tvb, offset, 1, ENC_BIG_ENDIAN);
212
0
  }
213
0
  else
214
0
  {
215
    /* Other */
216
0
    proto_tree_add_item(tree, hf_rach_est_cause,
217
0
                        tvb, offset, 1, ENC_BIG_ENDIAN);
218
219
0
    col_append_str(pinfo->cinfo, COL_INFO,
220
0
                    val_to_str(ec, rach_est_cause_vals, "Unknown (%u)"));
221
0
  }
222
223
  /* Retry counter */
224
0
  proto_tree_add_item(tree, hf_rach_retry_cnt,
225
0
                      tvb, offset, 1, ENC_BIG_ENDIAN);
226
227
  /* Precorrection Indication */
228
0
  proto_tree_add_item(tree, hf_rach_precorr,
229
0
                      tvb, offset + 1, 1, ENC_BIG_ENDIAN);
230
231
  /* Random Reference */
232
0
  proto_tree_add_item(tree, hf_rach_rand_ref,
233
0
                      tvb, offset + 1, 1, ENC_BIG_ENDIAN);
234
0
}
235
236
237
static const true_false_string rach_gps_pos_cpi_tfs = {
238
  "GPS position is current position",
239
  "GPS position is old position"
240
};
241
242
static void
243
rach_gps_pos_lat_fmt(gchar *s, guint32 v)
244
0
{
245
0
  gint32 sv = v;
246
247
0
  g_snprintf(s, ITEM_LABEL_LENGTH, "%.5f %s (%d)",
248
0
             abs(sv) / 2912.7f, sv < 0 ? "S" : "N", sv);
249
0
}
250
251
static void
252
rach_gps_pos_long_fmt(gchar *s, guint32 v)
253
0
{
254
0
  gint32 sv = v;
255
256
0
  g_snprintf(s, ITEM_LABEL_LENGTH, "%.5f %s (%d)",
257
0
             abs(sv) / 2912.70555f, sv < 0 ? "W" : "E", sv);
258
259
  /* FIXME: The specs says >0 is West ... but it doesn't seem to
260
   *        match real world captures !
261
   */
262
0
}
263
264
static void
265
dissect_gmr1_rach_gps_pos(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
266
0
{
267
0
  guint32 lat, lng;
268
269
  /* Check for NULL */
270
    /* Spec says that NULL is latitude == 0x40000 and longitude
271
     * is random. But from real capture it seems that
272
     * longitude == 0x80000 and latitude random is also NULL pos */
273
274
0
  lat = (tvb_get_ntohl(tvb, offset) >> 12) & 0x7ffff;
275
0
  lng = tvb_get_ntohl(tvb, offset + 1) & 0xfffff;
276
277
0
  if (lat == 0x40000) {
278
0
    proto_tree_add_int_format(tree, hf_rach_gps_pos_lat, tvb, offset, 5, lat,
279
0
                              "NULL GPS Position (latitude == 0x40000)");
280
0
    return;
281
0
  } else if (lng == 0x80000) {
282
0
    proto_tree_add_int_format(tree, hf_rach_gps_pos_long, tvb, offset, 5, lng,
283
0
                              "NULL GPS Position (longitude == 0x80000)");
284
0
    return;
285
0
  }
286
287
  /* CPI */
288
0
  proto_tree_add_item(tree, hf_rach_gps_pos_cpi,
289
0
                      tvb, offset, 1, ENC_BIG_ENDIAN);
290
291
  /* Latitude */
292
0
  proto_tree_add_item(tree, hf_rach_gps_pos_lat,
293
0
                      tvb, offset, 3, ENC_BIG_ENDIAN);
294
295
  /* Longitude */
296
0
  proto_tree_add_item(tree, hf_rach_gps_pos_long,
297
0
                      tvb, offset + 2, 3, ENC_BIG_ENDIAN);
298
0
}
299
300
301
static void
302
rach_sp_hplmn_id_fmt(gchar *s, guint32 v)
303
0
{
304
0
  if (v == 0xfffff) {
305
0
    g_snprintf(s, ITEM_LABEL_LENGTH, "%05x (Null)", v);
306
0
  } else if ((v & 0xf8000) == 0xf8000) {
307
0
    g_snprintf(s, ITEM_LABEL_LENGTH, "%05x (SP ID %4d)", v, v & 0x7fff);
308
0
  } else {
309
0
    g_snprintf(s, ITEM_LABEL_LENGTH, "%05x (HPLMN ID)", v);
310
0
  }
311
0
}
312
313
static const value_string rach_pd_vals[] = {
314
  { 0, "Fixed to 00 for this version of the protocol" },
315
  { 1, "Reserved" },
316
  { 2, "Reserved" },
317
  { 3, "Reserved" },
318
  { 0, NULL }
319
};
320
321
static void
322
rach_dialed_num_grp1234_fmt(gchar *s, guint32 v)
323
0
{
324
0
  if (v <= 999) {
325
0
    g_snprintf(s, ITEM_LABEL_LENGTH, "%03d", v);
326
0
  } else if (v == 1023) {
327
0
    g_snprintf(s, ITEM_LABEL_LENGTH,
328
0
      "All digits in the preceding group are valid (%d)", v);
329
0
  } else if (v == 1022) {
330
0
    g_snprintf(s, ITEM_LABEL_LENGTH,
331
0
      "First two digits in the preceding group are valid, "
332
0
      "and the third digit (i.e. 0) is padding (%d)", v);
333
0
  } else if (v == 1021) {
334
0
    g_snprintf(s, ITEM_LABEL_LENGTH,
335
0
      "First digit in the preceding group is valid, and "
336
0
      "the second and third 0s are padding (%d)", v);
337
0
  } else {
338
0
    g_snprintf(s, ITEM_LABEL_LENGTH, "Invalid (%d)", v);
339
0
  }
340
0
}
341
342
static void
343
rach_dialed_num_grp5_fmt(gchar *s, guint32 v)
344
0
{
345
0
  if (v >= 1100 && v <= 1199) {
346
0
    g_snprintf(s, ITEM_LABEL_LENGTH, "%02d (%d)", v - 1100, v);
347
0
  } else if (v >= 1200 && v <= 1209) {
348
0
    g_snprintf(s, ITEM_LABEL_LENGTH, "%01d (%d)", v - 1200, v);
349
0
  } else {
350
0
    rach_dialed_num_grp1234_fmt(s, v);
351
0
  }
352
0
}
353
354
static void
355
rach_gps_timestamp_fmt(gchar *s, guint32 v)
356
0
{
357
0
  if (v == 0xffff) {
358
0
    g_snprintf(s, ITEM_LABEL_LENGTH, ">= 65535 minutes or N/A (%04x)", v);
359
0
  } else {
360
0
    g_snprintf(s, ITEM_LABEL_LENGTH, "%d minutes (%04x)", v, v);
361
0
  }
362
0
}
363
364
static const true_false_string rach_gci_tfs = {
365
  "MES is GPS capable",
366
  "MES is not GPS capable"
367
};
368
369
static const true_false_string rach_r_tfs = {
370
  "Normal case",
371
  "Retry (see specs for details)"
372
};
373
374
static const true_false_string rach_o_tfs = {
375
  "Retry after failed optimal routing attempt",
376
  "Normal case"
377
};
378
379
static const value_string rach_number_type_vals[] = {
380
  { 0, "Unknown" },
381
  { 1, "International Number" },
382
  { 2, "National Number" },
383
  { 3, "Network-specific Number (operator access)" },
384
  { 4, "Dedicated Access short code" },
385
  { 5, "Reserved" },
386
  { 6, "Reserved" },
387
  { 7, "(N/A - Not MO Call)" },
388
  { 0, NULL }
389
};
390
391
static const value_string rach_gmprs_term_type_vals[] = {
392
  { 0x09, "Multislot class 2, Power class 1 (type C), Half Duplex, Handheld, Internal antenna, A/Gb interface, L-band" },
393
  { 0x0a, "Multislot class 3, Power class 1 (type C), Half Duplex, Handheld, Internal antenna, A/Gb interface, L-band" },
394
  { 0x0b, "Multislot class 4, Power class 1 (type C), Half Duplex, Handheld, Internal antenna, A/Gb interface, L-band" },
395
  { 0x0c, "Multislot class 1, Power class 1 (type C), Full Duplex, Handheld, Internal antenna, A/Gb interface, L-band" },
396
  { 0x0d, "Multislot class 1, Power class 9 (type D), Full Duplex, Fixed, Internal antenna, Gb interface, L-band" },
397
  { 0x0e, "Multislot class 1, Power class 9 (type D), Full Duplex, Fixed, Passive external antenna, Gb interface, L-band" },
398
  { 0x0f, "Multislot class 1, Power class 9 (type D), Full Duplex, Fixed, Active external antenna, Gb interface, L-band" },
399
  { 0x10, "Multislot class 4, Power class 1 (type E), Half Duplex, Handheld, Internal antenna, Iu-PS interface, S-band" },
400
  { 0x11, "Multislot class 5, Power class 1 (type E), Half Duplex, Handheld, Internal antenna, Iu-PS interface, S-band" },
401
  { 0x12, "Multislot class 5, Power class 1 (type E), Half Duplex, Handheld, Internal antenna, Iu-PS interface, S-band" },
402
  { 0x15, "Multislot class 3, Power class 1 (type F), Half Duplex, Handheld, Internal antenna, Iu-PS interface, S-band" },
403
  { 0x1a, "Multislot class 3, Power class 1 (type G), Half Duplex, Handheld, Internal antenna, Iu-PS interface, S-band" },
404
  { 0x1f, "Multislot class 1, Power class 2 (type H), Full Duplex, Vehicular, Internal antenna, Iu-PS interface, S-band" },
405
  { 0x20, "Multislot class 5, Power class 2 (type H), Full Duplex, Vehicular, Internal antenna, Iu-PS interface, S-band" },
406
  { 0x24, "Multislot class 1, Power class 9 (type I), Full Duplex, Fixed, Internal antenna, Iu-PS interface, S-band" },
407
  { 0x25, "Multislot class 1, Power class 9 (type I), Full Duplex, Fixed, Internal antenna, Iu-PS interface, S-band" },
408
  { 0x29, "Multislot class 3, (type J), Half Duplex, Handheld, Internal antenna, Iu-PS interface, L-band" },
409
  { 0x2e, "Multislot class 3, (type K), Half Duplex, Handheld, Internal antenna, Iu-PS interface, L-band" },
410
  { 0x33, "Multislot class 1, (type L), Full Duplex, Handheld, Internal antenna, Iu-PS interface, L-band" },
411
  { 0x38, "Multislot class 1, (type M), Full Duplex, Fixed, External antenna, Iu-PS interface, L-band" },
412
  { 0x40, "Reserved" },
413
  { 0x48, "Multislot class 1, Power class 8 (type A), Full Duplex, Fixed, Internal antenna, Gb interface, L-band" },
414
  { 0, NULL }
415
};
416
static value_string_ext rach_gmprs_term_type_ext_vals = VALUE_STRING_EXT_INIT(rach_gmprs_term_type_vals);
417
418
static const value_string rach_gmprs_radio_prio_vals[] = {
419
  { 0, "Radio Priority 1 (1=highest, 4=lowest)" },
420
  { 1, "Radio Priority 2 (1=highest, 4=lowest)" },
421
  { 2, "Radio Priority 3 (1=highest, 4=lowest)" },
422
  { 3, "Radio Priority 4 (1=highest, 4=lowest)" },
423
  { 0, NULL }
424
};
425
426
static const true_false_string rach_gmprs_rlc_mode_tfs = {
427
  "Unacknowledged",
428
  "Acknowledged"
429
};
430
431
static const true_false_string rach_gmprs_llc_mode_tfs = {
432
  "Data packets",
433
  "SACK/ACK packets"
434
};
435
436
static const value_string rach_gmprs_req_type_vals[] = {
437
  { 0x04, "Suspend - In Response to Alerting for circuit switched services" },
438
  { 0x06, "Suspend - MO Call" },
439
  { 0x07, "Resume" },
440
  { 0x08, "Suspend - Location Update" },
441
  { 0x09, "Suspend - IMSI Detach" },
442
  { 0x0a, "Suspend - Supplementary Services" },
443
  { 0x0b, "Suspend - Short Message Services" },
444
  { 0x0f, "Suspend - Emergency Call" },
445
  { 0, NULL }
446
};
447
448
static const value_string rach_gmprs_req_type_pag_resp_vals[] = {
449
  { 0x00, "Suspend - Answer to Paging" },
450
  { 0, NULL }
451
};
452
453
static int
454
_parse_dialed_number(gchar *s, int slen, tvbuff_t *tvb, int offset)
455
0
{
456
0
  guint16 grp[5];
457
0
  int rv, i, done;
458
459
0
  grp[0] = ((tvb_get_guint8(tvb, offset+0) & 0x3f) << 4) |
460
0
           ((tvb_get_guint8(tvb, offset+1) & 0xf0) >> 4);
461
0
  grp[1] = ((tvb_get_guint8(tvb, offset+1) & 0x0f) << 6) |
462
0
           ((tvb_get_guint8(tvb, offset+2) & 0xfc) >> 2);
463
0
  grp[2] = ((tvb_get_guint8(tvb, offset+2) & 0x03) << 8) |
464
0
             tvb_get_guint8(tvb, offset+3);
465
0
  grp[3] = ((tvb_get_guint8(tvb, offset+4) & 0xff) << 2) |
466
0
           ((tvb_get_guint8(tvb, offset+5) & 0xc0) >> 6);
467
0
  grp[4] = ((tvb_get_guint8(tvb, offset+5) & 0x3f) << 5) |
468
0
           ((tvb_get_guint8(tvb, offset+6) & 0xf8) >> 3);
469
470
0
  rv = 0;
471
0
  done = 0;
472
473
0
  for (i=0; i<4; i++)
474
0
  {
475
0
    if (grp[i+1] <= 999)
476
0
    {
477
      /* All digits of group are valid */
478
0
      rv += g_snprintf(s + rv, slen - rv, "%03d", grp[i]);
479
0
    }
480
0
    else if (grp[i+1] == 1023)
481
0
    {
482
      /* Last group and all digits are valid */
483
0
      rv += g_snprintf(s + rv, slen - rv, "%03d", grp[i]);
484
0
      done = 1;
485
0
      break;
486
0
    }
487
0
    else if (grp[i+1] == 1022)
488
0
    {
489
      /* Last group and first two digits are valid */
490
0
      rv += g_snprintf(s + rv, slen - rv, "%02d", grp[i] / 10);
491
0
      done = 1;
492
0
      break;
493
0
    }
494
0
    else if (grp[i+1] == 1021)
495
0
    {
496
      /* Last group and first digit is valid */
497
0
      rv += g_snprintf(s + rv, slen - rv, "%01d", grp[i] / 100);
498
0
      done = 1;
499
0
      break;
500
0
    }
501
0
    else if ((i==3) && (grp[i+1] >= 1100) && (grp[i+1] <= 1209))
502
0
    {
503
      /* All digits of group are valid */
504
0
      rv += g_snprintf(s + rv, slen - rv, "%03d", grp[i]);
505
0
    }
506
0
    else
507
0
    {
508
      /* Invalid */
509
0
      return g_snprintf(s, slen, "(Invalid)");
510
0
    }
511
0
  }
512
513
0
  if (!done) {
514
0
    if (grp[4] <= 999)
515
0
    {
516
      /* All digits are valid */
517
0
      rv += g_snprintf(s + rv, slen - rv, "%03d", grp[4]);
518
0
    }
519
0
    else if (grp[4] >= 1100 && grp[4] <= 1199)
520
0
    {
521
      /* Only two digits are valid */
522
0
      rv += g_snprintf(s + rv, slen - rv, "%02d", grp[4] - 1100);
523
0
    }
524
0
    else if (grp[4] >= 1200 && grp[4] <= 1209)
525
0
    {
526
      /* Only one digit is valid */
527
0
      rv += g_snprintf(s + rv, slen - rv, "%01d", grp[4] - 1200);
528
0
    }
529
0
    else
530
0
    {
531
      /* Invalid */
532
0
      return g_snprintf(s, slen, "(Invalid)");
533
0
    }
534
0
  }
535
536
0
  return rv;
537
0
}
538
539
static void
540
dissect_gmr1_rach_kls2(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *root_tree,
541
           int is_moc)
542
0
{
543
0
  proto_tree *tree = NULL;
544
0
  proto_item *dialed_num_item = NULL;
545
0
  proto_tree *dialed_num_tree = NULL, *gps_pos_tree = NULL;
546
547
  /* Tree */
548
0
  tree = proto_tree_add_subtree(
549
0
    root_tree, tvb, 2, 16,
550
0
    ett_rach_kls2, NULL, "Class-2 informations");
551
552
  /* MES Power Class */
553
0
  proto_tree_add_item(tree, hf_rach_mes_pwr_class,
554
0
                      tvb, offset, 1, ENC_BIG_ENDIAN);
555
556
  /* SP/HPLMN ID */
557
0
  proto_tree_add_item(tree, hf_rach_sp_hplmn_id,
558
0
                      tvb, offset, 3, ENC_BIG_ENDIAN);
559
560
  /* PD */
561
0
  proto_tree_add_item(tree, hf_rach_pd,
562
0
                      tvb, offset + 3, 1, ENC_BIG_ENDIAN);
563
564
565
  /* Is it a MO call ? */
566
0
  if (is_moc) {
567
0
    gchar s[32];
568
569
    /* Dialed number */
570
      /* Parse number */
571
0
    _parse_dialed_number(s, sizeof(s), tvb, offset + 3);
572
573
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", s);
574
575
      /* Base item */
576
0
    dialed_num_item = proto_tree_add_string(
577
0
      tree, hf_rach_number, tvb, offset + 3, 7, s);
578
579
0
    dialed_num_tree = proto_item_add_subtree(
580
0
      dialed_num_item, ett_rach_dialed_num);
581
582
      /* Group 1 */
583
0
    proto_tree_add_item(dialed_num_tree, hf_rach_number_grp1,
584
0
                        tvb, offset + 3, 2, ENC_BIG_ENDIAN);
585
586
      /* Group 2 */
587
0
    proto_tree_add_item(dialed_num_tree, hf_rach_number_grp2,
588
0
                        tvb, offset + 4, 2, ENC_BIG_ENDIAN);
589
590
      /* Group 3 */
591
0
    proto_tree_add_item(dialed_num_tree, hf_rach_number_grp3,
592
0
                        tvb, offset + 5, 2, ENC_BIG_ENDIAN);
593
594
      /* Group 4 */
595
0
    proto_tree_add_item(dialed_num_tree, hf_rach_number_grp4,
596
0
                        tvb, offset + 7, 2, ENC_BIG_ENDIAN);
597
598
      /* Group 5 */
599
0
    proto_tree_add_item(dialed_num_tree, hf_rach_number_grp5,
600
0
                        tvb, offset + 8, 2, ENC_BIG_ENDIAN);
601
0
  } else {
602
    /* MSC ID */
603
0
    proto_tree_add_item(tree, hf_rach_msc_id,
604
0
                        tvb, offset + 3, 1, ENC_BIG_ENDIAN);
605
606
    /* GPS timestamp */
607
0
    proto_tree_add_item(tree, hf_rach_gps_timestamp,
608
0
                        tvb, offset + 4, 2, ENC_BIG_ENDIAN);
609
610
    /* Software version number */
611
0
    proto_tree_add_item(tree, hf_rach_software_version,
612
0
                        tvb, offset + 6, 1, ENC_BIG_ENDIAN);
613
614
    /* Spare */
615
0
    proto_tree_add_item(tree, hf_rach_spare,
616
0
                        tvb, offset + 6, 1, ENC_BIG_ENDIAN);
617
0
  }
618
619
  /* GCI */
620
0
  proto_tree_add_item(tree, hf_rach_gci,
621
0
                      tvb, offset + 9, 1, ENC_BIG_ENDIAN);
622
623
  /* R */
624
0
  proto_tree_add_item(tree, hf_rach_r,
625
0
                      tvb, offset + 9, 1, ENC_BIG_ENDIAN);
626
627
  /* O */
628
0
  proto_tree_add_item(tree, hf_rach_o,
629
0
                      tvb, offset + 9, 1, ENC_BIG_ENDIAN);
630
631
  /* GPS Position */
632
0
  gps_pos_tree = proto_tree_add_subtree(
633
0
    tree, tvb, offset + 10, 5,
634
0
    ett_rach_gps_pos, NULL, "GPS Position");
635
636
0
  dissect_gmr1_rach_gps_pos(tvb, offset + 10, pinfo, gps_pos_tree);
637
638
  /* Number type */
639
0
  proto_tree_add_item(tree, hf_rach_number_type,
640
0
                      tvb, offset + 15, 1, ENC_BIG_ENDIAN);
641
0
}
642
643
static const crumb_spec_t rach_gmprs_type1_term_type_crumbs[] = {
644
  {  0, 4 },
645
  { 29, 3 },
646
  {  0, 0 }
647
};
648
649
static const crumb_spec_t rach_gmprs_num_rlc_blks_crumbs[] = {
650
  {  0, 8 },
651
  { 14, 2 },
652
  {  0, 0 }
653
};
654
655
static void
656
dissect_gmprs_rach_type1_kls2(tvbuff_t *tvb, int offset,
657
                              packet_info *pinfo, proto_tree *root_tree, int is_pdt)
658
0
{
659
0
  proto_tree *tree = NULL;
660
0
  proto_tree *gps_pos_tree = NULL;
661
0
  guint8 term_type;
662
0
  int is_class_d;
663
664
  /* Tree */
665
0
  tree = proto_tree_add_subtree(
666
0
    root_tree, tvb, 2, 16,
667
0
    ett_rach_gmprs_type1_kls2, NULL, "GmPRS Type-1 Class-2 informations");
668
669
  /* GmPRS Terminal Type */
670
0
  proto_tree_add_split_bits_item_ret_val(
671
0
    tree, hf_rach_gmprs_term_type,
672
0
    tvb, offset << 3,
673
0
    rach_gmprs_type1_term_type_crumbs,
674
0
    NULL);
675
676
0
  term_type = ((tvb_get_guint8(tvb, offset) >> 1) & 0x78 ) |
677
0
              ( tvb_get_guint8(tvb, offset + 3)   & 0x07);
678
679
0
  is_class_d = (term_type == 0x0d) ||
680
0
               (term_type == 0x0e) ||
681
0
               (term_type == 0x0f);
682
683
  /* Class D terminal ? */
684
0
  if (is_class_d) {
685
    /* DL Peak Throughput */
686
0
    proto_tree_add_item(tree, hf_rach_gmprs_dl_peak_tput,
687
0
                        tvb, offset, 1, ENC_BIG_ENDIAN);
688
689
    /* Reserved */
690
0
    proto_tree_add_item(tree, hf_rach_gmprs_reserved1,
691
0
                        tvb, offset, 2, ENC_BIG_ENDIAN);
692
0
  } else {
693
    /* SP/HPLMN ID */
694
0
    proto_tree_add_item(tree, hf_rach_sp_hplmn_id,
695
0
            tvb, offset, 3, ENC_BIG_ENDIAN);
696
0
  }
697
698
  /* Radio Priority */
699
0
  proto_tree_add_item(tree, hf_rach_gmprs_radio_prio,
700
0
                      tvb, offset + 3, 1, ENC_BIG_ENDIAN);
701
702
  /* Spare */
703
0
  proto_tree_add_item(tree, hf_rach_gmprs_spare1,
704
0
                      tvb, offset + 3, 1, ENC_BIG_ENDIAN);
705
706
  /* PD */
707
0
  proto_tree_add_item(tree, hf_rach_pd,
708
0
                      tvb, offset + 3, 1, ENC_BIG_ENDIAN);
709
710
  /* TLLI */
711
0
  proto_tree_add_item(tree, hf_rach_gmprs_tlli,
712
0
                      tvb, offset + 4, 4, ENC_BIG_ENDIAN);
713
714
  /* Is it for Packet Data Transfer ? */
715
0
  if (is_pdt) {
716
    /* Number of RLC blocks */
717
0
    proto_tree_add_split_bits_item_ret_val(
718
0
      tree, hf_rach_gmprs_num_rlc_blks,
719
0
      tvb, (offset + 8) << 3,
720
0
      rach_gmprs_num_rlc_blks_crumbs,
721
0
      NULL);
722
723
    /* (UL) Peak Throughput */
724
0
    proto_tree_add_item(tree, is_class_d ?
725
0
                            hf_rach_gmprs_ul_peak_tput :
726
0
                            hf_rach_gmprs_peak_tput,
727
0
                        tvb, offset + 9, 1, ENC_BIG_ENDIAN);
728
729
    /* Spare */
730
0
    proto_tree_add_item(tree, hf_rach_gmprs_spare2,
731
0
            tvb, offset + 9, 1, ENC_BIG_ENDIAN);
732
0
  } else {
733
    /* GPS timestamp */
734
0
    proto_tree_add_item(tree, hf_rach_gps_timestamp,
735
0
                        tvb, offset + 8, 2, ENC_BIG_ENDIAN);
736
0
  }
737
738
  /* GPS Position */
739
0
  gps_pos_tree = proto_tree_add_subtree(
740
0
    tree, tvb, offset + 10, 5,
741
0
    ett_rach_gps_pos, NULL, "GPS Position");
742
743
0
  dissect_gmr1_rach_gps_pos(tvb, offset + 10, pinfo, gps_pos_tree);
744
745
  /* RLC mode */
746
    /* Off-the-air data shows bit is sometimes set even
747
     * when not a PDT ... */
748
0
  proto_tree_add_item(tree, hf_rach_gmprs_rlc_mode,
749
0
                      tvb, offset + 15, 1, ENC_BIG_ENDIAN);
750
751
  /* LLC mode */
752
    /* Off-the-air data shows bit is sometimes set even
753
     * when not a PDT ... */
754
0
  proto_tree_add_item(tree, hf_rach_gmprs_llc_mode,
755
0
                      tvb, offset + 15, 1, ENC_BIG_ENDIAN);
756
757
  /* Spare */
758
0
  proto_tree_add_item(tree, hf_rach_gmprs_spare3,
759
0
          tvb, offset + 15, 1, ENC_BIG_ENDIAN);
760
0
}
761
762
static const crumb_spec_t rach_gmprs_type2_term_type_crumbs[] = {
763
  {  0, 4 },
764
  { 64, 3 },
765
  {  0, 0 }
766
};
767
768
static void
769
dissect_gmprs_rach_type2_kls2(tvbuff_t *tvb, int offset,
770
                              packet_info *pinfo, proto_tree *root_tree)
771
0
{
772
0
  proto_tree *tree = NULL;
773
0
  proto_tree *gps_pos_tree = NULL;
774
0
  guint8 req_type;
775
776
  /* Tree */
777
0
  tree = proto_tree_add_subtree(
778
0
    root_tree, tvb, 2, 16,
779
0
    ett_rach_gmprs_type2_kls2, NULL, "GmPRS Type-2 Class-2 informations");
780
781
  /* GmPRS Terminal type */
782
0
  proto_tree_add_split_bits_item_ret_val(
783
0
    tree, hf_rach_gmprs_term_type,
784
0
    tvb, offset << 3,
785
0
    rach_gmprs_type2_term_type_crumbs,
786
0
    NULL);
787
788
  /* SP/HPLMN ID */
789
0
  proto_tree_add_item(tree, hf_rach_sp_hplmn_id,
790
0
          tvb, offset, 3, ENC_BIG_ENDIAN);
791
792
  /* PD */
793
0
  proto_tree_add_item(tree, hf_rach_pd,
794
0
                      tvb, offset + 3, 1, ENC_BIG_ENDIAN);
795
796
  /* MSC ID */
797
0
  proto_tree_add_item(tree, hf_rach_msc_id,
798
0
                      tvb, offset + 3, 1, ENC_BIG_ENDIAN);
799
800
  /* TLLI */
801
0
  proto_tree_add_item(tree, hf_rach_gmprs_tlli,
802
0
                      tvb, offset + 4, 4, ENC_BIG_ENDIAN);
803
804
  /* Request type */
805
0
  req_type = tvb_get_guint8(tvb, offset + 8) & 0x1f;
806
807
0
  if ((req_type & 0x1c) == 0) {
808
    /* Paging response */
809
0
    proto_item *rt_item = proto_tree_add_item(
810
0
      tree, hf_rach_gmprs_req_type_pag_resp,
811
0
      tvb, offset + 8, 1, ENC_BIG_ENDIAN);
812
813
0
    proto_tree *rt_tree = proto_item_add_subtree(rt_item, ett_rach_gmprs_req_type);
814
815
0
    col_append_str(pinfo->cinfo, COL_INFO, "Paging response ");
816
817
    /* Channel Needed */
818
0
    proto_tree_add_item(rt_tree, hf_rach_gmprs_chan_needed,
819
0
                        tvb, offset + 8, 1, ENC_BIG_ENDIAN);
820
0
  } else {
821
    /* Other */
822
0
    proto_tree_add_item(tree, hf_rach_gmprs_req_type,
823
0
            tvb, offset + 8, 1, ENC_BIG_ENDIAN);
824
825
0
    col_append_str(pinfo->cinfo, COL_INFO,
826
0
                    val_to_str(req_type, rach_gmprs_req_type_vals, "Unknown (%u)"));
827
0
  }
828
829
  /* Software version number */
830
0
  proto_tree_add_item(tree, hf_rach_software_version,
831
0
                      tvb, offset + 9, 1, ENC_BIG_ENDIAN);
832
833
  /* Spare */
834
0
  proto_tree_add_item(tree, hf_rach_spare,
835
0
                      tvb, offset + 9, 1, ENC_BIG_ENDIAN);
836
837
  /* GPS Position */
838
0
  gps_pos_tree = proto_tree_add_subtree(
839
0
    tree, tvb, offset + 10, 5,
840
0
    ett_rach_gps_pos, NULL, "GPS Position");
841
842
0
  dissect_gmr1_rach_gps_pos(tvb, offset + 10, pinfo, gps_pos_tree);
843
844
  /* GCI */
845
0
  proto_tree_add_item(tree, hf_rach_gci,
846
0
                      tvb, offset + 15, 1, ENC_BIG_ENDIAN);
847
848
  /* R */
849
0
  proto_tree_add_item(tree, hf_rach_r,
850
0
                      tvb, offset + 15, 1, ENC_BIG_ENDIAN);
851
852
  /* O */
853
0
  proto_tree_add_item(tree, hf_rach_o,
854
0
                      tvb, offset + 15, 1, ENC_BIG_ENDIAN);
855
0
}
856
857
static int
858
dissect_gmr1_rach(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
859
0
{
860
0
  const int RACH_IE_CLASS1    = (1 << 0);
861
0
  const int RACH_IE_CLASS2_GMR1   = (1 << 1);
862
0
  const int RACH_IE_CLASS2_GMPRS_TYPE1  = (1 << 2);
863
0
  const int RACH_IE_CLASS2_GMPRS_TYPE2  = (1 << 3);
864
865
0
  proto_item *rach_item;
866
0
  proto_tree *rach_tree;
867
0
  const char *desc;
868
0
  int len, is_moc, is_pdt, ies;
869
870
0
  len = tvb_reported_length(tvb);
871
872
0
  desc = "GMR-1 Channel Request (RACH)";
873
0
  ies  = 0;
874
875
0
  if (len == 18) {
876
0
    guint8 ec = (tvb_get_guint8(tvb, 0) >> 1) & 0x1f;
877
878
0
    ies |= RACH_IE_CLASS1;
879
880
0
    if ((ec == 13) || (ec == 14)) {
881
0
      desc = "GMR-1 GmPRS Channel Request Type 1 (RACH)";
882
0
      ies |= RACH_IE_CLASS2_GMPRS_TYPE1;
883
0
    } else if (ec == 7) {
884
0
      desc = "GMR-1 GmPRS Channel Request Type 2 (RACH)";
885
0
      ies |= RACH_IE_CLASS2_GMPRS_TYPE2;
886
#if 0 /* Fix -Wduplicated-branches */
887
    } else if (ec == 12) {
888
      /* Position verification exists in both GMR-1 and GmPRS-1
889
       * I have no idea how to differentiate them ... but from
890
       * off-the-air data, it seems it used the GMR-1 format */
891
      ies |= RACH_IE_CLASS2_GMR1;
892
#endif
893
0
    } else {
894
0
      ies |= RACH_IE_CLASS2_GMR1;
895
0
    }
896
0
  }
897
898
0
  rach_item = proto_tree_add_protocol_format(
899
0
    tree, proto_gmr1_rach, tvb, 0, len, "%s", desc);
900
0
  rach_tree = proto_item_add_subtree(rach_item, ett_rach_msg);
901
902
0
  if (!ies) {
903
0
    col_append_str(pinfo->cinfo, COL_INFO, "(Invalid)");
904
0
    call_data_dissector(tvb, pinfo, tree);
905
0
    return tvb_captured_length(tvb);
906
0
  }
907
908
0
  col_append_str(pinfo->cinfo, COL_INFO, "(RACH) ");
909
910
0
  if (ies & RACH_IE_CLASS1)
911
0
    dissect_gmr1_rach_kls1(tvb, 0, pinfo, rach_tree, &is_moc, &is_pdt);
912
913
0
  if (ies & RACH_IE_CLASS2_GMR1)
914
0
    dissect_gmr1_rach_kls2(tvb, 2, pinfo, rach_tree, is_moc);
915
916
0
  if (ies & RACH_IE_CLASS2_GMPRS_TYPE1)
917
0
    dissect_gmprs_rach_type1_kls2(tvb, 2, pinfo, rach_tree, is_pdt);
918
919
0
  if (ies & RACH_IE_CLASS2_GMPRS_TYPE2)
920
0
    dissect_gmprs_rach_type2_kls2(tvb, 2, pinfo, rach_tree);
921
922
0
  return tvb_captured_length(tvb);
923
0
}
924
925
void
926
proto_register_gmr1_rach(void)
927
5.41k
{
928
5.41k
  static hf_register_info hf[] = {
929
5.41k
    { &hf_rach_prio,
930
5.41k
      { "Priority", "gmr1.rach.priority",
931
5.41k
        FT_BOOLEAN, 8, TFS(&rach_prio_tfs), 0x01,
932
5.41k
        NULL, HFILL }
933
5.41k
    },
934
5.41k
    { &hf_rach_est_cause,
935
5.41k
      { "Establishment Cause", "gmr1.rach.est_cause",
936
5.41k
        FT_UINT8, BASE_HEX, VALS(rach_est_cause_vals), 0x3e,
937
5.41k
        NULL, HFILL }
938
5.41k
    },
939
5.41k
    { &hf_rach_est_cause_moc,
940
5.41k
      { "Establishment Cause", "gmr1.rach.est_cause.moc",
941
5.41k
        FT_UINT8, BASE_HEX, VALS(rach_est_cause_moc_vals), 0x20,
942
5.41k
        NULL, HFILL }
943
5.41k
    },
944
5.41k
    { &hf_rach_est_cause_pag_resp,
945
5.41k
      { "Establishment Cause", "gmr1.rach.est_cause.pag_resp",
946
5.41k
        FT_UINT8, BASE_HEX, VALS(rach_est_cause_pag_resp_vals), 0x38,
947
5.41k
        NULL, HFILL }
948
5.41k
    },
949
5.41k
    { &hf_rach_num_plan,
950
5.41k
      { "Numbering Plan Identification", "gmr1.rach.numbering_plan",
951
5.41k
        FT_UINT8, BASE_DEC, VALS(rach_num_plan_vals), 0x1e,
952
5.41k
        NULL, HFILL }
953
5.41k
    },
954
5.41k
    { &hf_rach_chan_needed,
955
5.41k
      { "Channel Needed", "gmr1.rach.chan_needed",
956
5.41k
        FT_UINT8, BASE_DEC, VALS(rach_chan_needed_vals), 0x06,
957
5.41k
        "Echoed from Paging Request", HFILL }
958
5.41k
    },
959
5.41k
    { &hf_rach_retry_cnt,
960
5.41k
      { "Retry Counter", "gmr1.rach.retry_counter",
961
5.41k
        FT_UINT8, BASE_DEC, NULL, 0xc0,
962
5.41k
        "Retransmission count for current access attempt", HFILL }
963
5.41k
    },
964
5.41k
    { &hf_rach_precorr,
965
5.41k
      { "Precorrection Indication", "gmr1.rach.precorr_ind",
966
5.41k
        FT_UINT8, BASE_DEC, VALS(rach_precorr_vals), 0xe0,
967
5.41k
        "This is the timing correction applied to RACH while "
968
5.41k
        "sending this message. See GMR 05.010.", HFILL }
969
5.41k
    },
970
5.41k
    { &hf_rach_rand_ref,
971
5.41k
      { "Random Reference", "gmr1.rach.random_reference",
972
5.41k
        FT_UINT8, BASE_HEX, NULL, 0x1f,
973
5.41k
        "A random number of 5 bits", HFILL }
974
5.41k
    },
975
5.41k
    { &hf_rach_gps_pos_cpi,
976
5.41k
      { "CPI", "gmr1.rach.gps_pos.cpi",
977
5.41k
        FT_BOOLEAN, 8, TFS(&rach_gps_pos_cpi_tfs), 0x80,
978
5.41k
        "Current Position Indicator", HFILL }
979
5.41k
    },
980
5.41k
    { &hf_rach_gps_pos_lat,
981
5.41k
      { "Latitude", "gmr1.rach.gps_pos.latitude",
982
5.41k
        FT_INT24, BASE_CUSTOM, CF_FUNC(rach_gps_pos_lat_fmt), 0x7ffff0,
983
5.41k
        NULL, HFILL }
984
5.41k
    },
985
5.41k
    { &hf_rach_gps_pos_long,
986
5.41k
      { "Longitude", "gmr1.rach.gps_pos.longitude",
987
5.41k
        FT_INT24, BASE_CUSTOM, CF_FUNC(rach_gps_pos_long_fmt), 0x0fffff,
988
5.41k
        NULL, HFILL }
989
5.41k
    },
990
5.41k
    { &hf_rach_mes_pwr_class,
991
5.41k
      { "MES Power Class", "gmr1.rach.mes_power_class",
992
5.41k
        FT_UINT8, BASE_DEC, NULL, 0xf0,
993
5.41k
        "See GMR 05.005 for infos", HFILL }
994
5.41k
    },
995
5.41k
    { &hf_rach_sp_hplmn_id,
996
5.41k
      { "SP/HPLMN ID", "gmr1.rach.sp_hplmn_id",
997
5.41k
        FT_UINT24, BASE_CUSTOM, CF_FUNC(rach_sp_hplmn_id_fmt), 0x0fffff,
998
5.41k
        NULL, HFILL }
999
5.41k
    },
1000
5.41k
    { &hf_rach_pd,
1001
5.41k
      { "PD", "gmr1.rach.pd",
1002
5.41k
        FT_UINT8, BASE_DEC, VALS(rach_pd_vals), 0xc0,
1003
5.41k
        "Protocol Discriminator", HFILL }
1004
5.41k
    },
1005
5.41k
    { &hf_rach_number,
1006
5.41k
      { "Dialed Number", "gmr1.rach.number",
1007
5.41k
        FT_STRING, BASE_NONE, NULL, 0x00,
1008
5.41k
        NULL, HFILL }
1009
5.41k
    },
1010
5.41k
    { &hf_rach_number_grp1,
1011
5.41k
      { "Group 1", "gmr1.rach.number.grp1",
1012
5.41k
        FT_UINT16, BASE_CUSTOM, CF_FUNC(rach_dialed_num_grp1234_fmt), 0x3ff0,
1013
5.41k
        NULL, HFILL }
1014
5.41k
    },
1015
5.41k
    { &hf_rach_number_grp2,
1016
5.41k
      { "Group 2", "gmr1.rach.number.grp2",
1017
5.41k
        FT_UINT16, BASE_CUSTOM, CF_FUNC(rach_dialed_num_grp1234_fmt), 0x0ffc,
1018
5.41k
        NULL, HFILL }
1019
5.41k
    },
1020
5.41k
    { &hf_rach_number_grp3,
1021
5.41k
      { "Group 3", "gmr1.rach.number.grp3",
1022
5.41k
        FT_UINT16, BASE_CUSTOM, CF_FUNC(rach_dialed_num_grp1234_fmt), 0x03ff,
1023
5.41k
        NULL, HFILL }
1024
5.41k
    },
1025
5.41k
    { &hf_rach_number_grp4,
1026
5.41k
      { "Group 4", "gmr1.rach.number.grp4",
1027
5.41k
        FT_UINT16, BASE_CUSTOM, CF_FUNC(rach_dialed_num_grp1234_fmt), 0xffc0,
1028
5.41k
        NULL, HFILL }
1029
5.41k
    },
1030
5.41k
    { &hf_rach_number_grp5,
1031
5.41k
      { "Group 5", "gmr1.rach.number.grp5",
1032
5.41k
        FT_UINT16, BASE_CUSTOM, CF_FUNC(rach_dialed_num_grp5_fmt), 0x3ff8,
1033
5.41k
        NULL, HFILL }
1034
5.41k
    },
1035
5.41k
    { &hf_rach_msc_id,
1036
5.41k
      { "MSC ID", "gmr1.rach.msc_id",
1037
5.41k
        FT_UINT8, BASE_DEC, NULL, 0x3f,
1038
5.41k
        NULL, HFILL }
1039
5.41k
    },
1040
5.41k
    { &hf_rach_gps_timestamp,
1041
5.41k
      { "GPS Timestamp", "gmr1.rach.gps_timestamp",
1042
5.41k
        FT_UINT16, BASE_CUSTOM, CF_FUNC(rach_gps_timestamp_fmt), 0xffff,
1043
5.41k
        NULL, HFILL }
1044
5.41k
    },
1045
5.41k
    { &hf_rach_software_version,
1046
5.41k
      { "Software Version", "gmr1.rach.software_version",
1047
5.41k
        FT_UINT8, BASE_DEC, NULL, 0xfe,
1048
5.41k
        NULL, HFILL }
1049
5.41k
    },
1050
5.41k
    { &hf_rach_spare,
1051
5.41k
      { "Spare", "gmr1.rach.spare",
1052
5.41k
        FT_UINT32, BASE_DEC, NULL, 0x01fffff8,
1053
5.41k
        NULL, HFILL }
1054
5.41k
    },
1055
5.41k
    { &hf_rach_gci,
1056
5.41k
      { "GCI", "gmr1.rach.gci",
1057
5.41k
        FT_BOOLEAN, 8, TFS(&rach_gci_tfs), 0x01,
1058
5.41k
        "GPS Capability Indicator", HFILL }
1059
5.41k
    },
1060
5.41k
    { &hf_rach_r,
1061
5.41k
      { "R", "gmr1.rach.r",
1062
5.41k
        FT_BOOLEAN, 8, TFS(&rach_r_tfs), 0x02,
1063
5.41k
        "See GMR 04.008 10.1.8 for full description" , HFILL }
1064
5.41k
    },
1065
5.41k
    { &hf_rach_o,
1066
5.41k
      { "O", "gmr1.rach.o",
1067
5.41k
        FT_BOOLEAN, 8, TFS(&rach_o_tfs), 0x04,
1068
5.41k
        "See GMR 04.008 10.1.8 for full description", HFILL }
1069
5.41k
    },
1070
5.41k
    { &hf_rach_number_type,
1071
5.41k
      { "Number Type", "gmr1.rach.number_type",
1072
5.41k
        FT_UINT8, BASE_DEC, VALS(rach_number_type_vals), 0x07,
1073
5.41k
        "For MO Call only", HFILL }
1074
5.41k
    },
1075
5.41k
    { &hf_rach_gmprs_term_type,
1076
5.41k
      { "GmPRS Terminal Type", "gmr1.rach.gmprs_term_type",
1077
5.41k
        FT_UINT8, BASE_DEC | BASE_EXT_STRING, &rach_gmprs_term_type_ext_vals, 0x00,
1078
5.41k
        "See GMR-1 3G 45.002 Annex C for infos", HFILL }
1079
5.41k
    },
1080
5.41k
    { &hf_rach_gmprs_radio_prio,
1081
5.41k
      { "Radio Priority", "gmr1.rach.gmprs_radio_prio",
1082
5.41k
        FT_UINT8, BASE_DEC, VALS(rach_gmprs_radio_prio_vals), 0x18,
1083
5.41k
        "See GMPRS-1 04.060 for infos", HFILL }
1084
5.41k
    },
1085
5.41k
    { &hf_rach_gmprs_tlli,
1086
5.41k
      { "TLLI", "gmr1.rach.gmprs_tlli",
1087
5.41k
        FT_UINT32, BASE_HEX, NULL, 0x00,
1088
5.41k
        "See GMPRS-1 04.060 for infos", HFILL }
1089
5.41k
    },
1090
5.41k
    { &hf_rach_gmprs_num_rlc_blks,
1091
5.41k
      { "Number of RLC blocks", "gmr1.rach.gmprs_num_rlc_blks",
1092
5.41k
        FT_UINT16, BASE_DEC, NULL, 0x00,
1093
5.41k
        "See GMPRS-1 04.060 12.31 for infos", HFILL }
1094
5.41k
    },
1095
5.41k
    { &hf_rach_gmprs_peak_tput,
1096
5.41k
      { "Peak Throughput", "gmr1.rach.gmprs_peak_tput",
1097
5.41k
        FT_UINT8, BASE_DEC, NULL, 0x3c,
1098
5.41k
        "See GMPRS-1 04.060 for infos", HFILL }
1099
5.41k
    },
1100
5.41k
    { &hf_rach_gmprs_dl_peak_tput,
1101
5.41k
      { "DL Peak Throughput", "gmr1.rach.gmprs_dl_peak_tput",
1102
5.41k
        FT_UINT8, BASE_DEC, NULL, 0x0f,
1103
5.41k
        "See 3GPP TS 23.060 for infos", HFILL }
1104
5.41k
    },
1105
5.41k
    { &hf_rach_gmprs_ul_peak_tput,
1106
5.41k
      { "UL Peak Throughput", "gmr1.rach.gmprs_ul_peak_tput",
1107
5.41k
        FT_UINT8, BASE_DEC, NULL, 0x3c,
1108
5.41k
        "See 3GPP TS 23.060 for infos", HFILL }
1109
5.41k
    },
1110
5.41k
    { &hf_rach_gmprs_rlc_mode,
1111
5.41k
      { "RLC mode", "gmr1.rach.gmprs_rlc_mode",
1112
5.41k
        FT_BOOLEAN, 8, TFS(&rach_gmprs_rlc_mode_tfs), 0x01,
1113
5.41k
        NULL, HFILL }
1114
5.41k
    },
1115
5.41k
    { &hf_rach_gmprs_llc_mode,
1116
5.41k
      { "LLC mode", "gmr1.rach.gmprs_llc_mode",
1117
5.41k
        FT_BOOLEAN, 8, TFS(&rach_gmprs_llc_mode_tfs), 0x02,
1118
5.41k
        NULL, HFILL }
1119
5.41k
    },
1120
5.41k
    { &hf_rach_gmprs_spare1,
1121
5.41k
      { "Spare", "gmr1.rach.gmprs_spare1",
1122
5.41k
        FT_UINT8, BASE_DEC, NULL, 0x20,
1123
5.41k
        NULL, HFILL }
1124
5.41k
    },
1125
5.41k
    { &hf_rach_gmprs_spare2,
1126
5.41k
      { "Spare", "gmr1.rach.gmprs_spare2",
1127
5.41k
        FT_UINT8, BASE_DEC, NULL, 0xc0,
1128
5.41k
        NULL, HFILL }
1129
5.41k
    },
1130
5.41k
    { &hf_rach_gmprs_spare3,
1131
5.41k
      { "Spare", "gmr1.rach.gmprs_spare3",
1132
5.41k
        FT_UINT8, BASE_DEC, NULL, 0x04,
1133
5.41k
        NULL, HFILL }
1134
5.41k
    },
1135
5.41k
    { &hf_rach_gmprs_reserved1,
1136
5.41k
      { "Reserved", "gmr1.rach.gmprs_reserved1",
1137
5.41k
        FT_UINT16, BASE_HEX, NULL, 0xffff,
1138
5.41k
        NULL, HFILL }
1139
5.41k
    },
1140
5.41k
    { &hf_rach_gmprs_req_type,
1141
5.41k
      { "Request Type", "gmr1.rach.gmprs_req_type",
1142
5.41k
        FT_UINT8, BASE_DEC, VALS(rach_gmprs_req_type_vals), 0x1f,
1143
5.41k
        NULL, HFILL }
1144
5.41k
    },
1145
5.41k
    { &hf_rach_gmprs_req_type_pag_resp,
1146
5.41k
      { "Request Type", "gmr1.rach.gmprs_req_type.pag_resp",
1147
5.41k
        FT_UINT8, BASE_DEC, VALS(rach_gmprs_req_type_pag_resp_vals), 0x1c,
1148
5.41k
        NULL, HFILL }
1149
5.41k
    },
1150
5.41k
    { &hf_rach_gmprs_chan_needed,
1151
5.41k
      { "Channel Needed", "gmr1.rach.gmprs_chan_needed",
1152
5.41k
        FT_UINT8, BASE_DEC, VALS(rach_chan_needed_vals), 0x03,
1153
5.41k
        "Echoed from Paging Request", HFILL }
1154
5.41k
    },
1155
5.41k
  };
1156
1157
5.41k
  static gint *ett[] = {
1158
5.41k
    &ett_rach_msg,
1159
5.41k
    &ett_rach_kls1,
1160
5.41k
    &ett_rach_kls2,
1161
5.41k
    &ett_rach_gmprs_type1_kls2,
1162
5.41k
    &ett_rach_gmprs_type2_kls2,
1163
5.41k
    &ett_rach_est_cause,
1164
5.41k
    &ett_rach_dialed_num,
1165
5.41k
    &ett_rach_gps_pos,
1166
5.41k
    &ett_rach_gmprs_req_type,
1167
5.41k
  };
1168
1169
5.41k
  proto_gmr1_rach = proto_register_protocol("GEO-Mobile Radio (1) RACH", "GMR-1 RACH", "gmr1.rach");
1170
1171
5.41k
  proto_register_field_array(proto_gmr1_rach, hf, array_length(hf));
1172
5.41k
  proto_register_subtree_array(ett, array_length(ett));
1173
1174
5.41k
  register_dissector("gmr1_rach", dissect_gmr1_rach, proto_gmr1_rach);
1175
5.41k
}
1176
1177
/*
1178
 * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
1179
 *
1180
 * Local variables:
1181
 * c-basic-offset: 8
1182
 * tab-width: 8
1183
 * indent-tabs-mode: t
1184
 * End:
1185
 *
1186
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1187
 * :indentSize=8:tabSize=8:noTabs=false:
1188
 */