From Didier Gautheron:
[obnox/wireshark/wip.git] / epan / dissectors / packet-amr.c
1 /* packet-amr.c
2  * Routines for AMR dissection
3  * Copyright 2005-2008, Anders Broman <anders.broman[at]ericsson.com>
4  *
5  * $Id$
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  * 
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  * 
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  * 
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24  *
25  * References:
26  * RFC 3267  http://www.ietf.org/rfc/rfc3267.txt?number=3267
27  * 3GPP TS 26.101 for AMR-NB, 3GPP TS 26.201 for AMR-WB
28  */
29
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37
38 #include <glib.h>
39
40 #include <epan/packet.h>
41 #include <epan/proto.h>
42 #include <epan/expert.h>
43 #include <epan/oids.h>
44 #include <epan/asn1.h>
45
46 #include <epan/prefs.h>
47
48 #define AMR_NB_SID 8
49 #define AMR_WB_SID 9
50 #define AMR_NO_TRANS 15
51
52 #define AMR_NB 0
53 #define AMR_WB 1
54
55 /* Initialize the protocol and registered fields */
56 static int proto_amr            = -1;
57 static int hf_amr_nb_cmr        = -1;
58 static int hf_amr_wb_cmr        = -1;
59 static int hf_amr_reserved      = -1;
60 static int hf_amr_toc_f         = -1;
61 static int hf_amr_nb_toc_ft     = -1;
62 static int hf_amr_wb_toc_ft     = -1;
63 static int hf_amr_toc_q         = -1;
64
65 static int hf_amr_nb_if1_ft = -1;
66 static int hf_amr_wb_if1_ft = -1;
67 static int hf_amr_if1_fqi = -1;
68 static int hf_amr_nb_if1_mode_req = -1;
69 static int hf_amr_wb_if1_mode_req = -1;
70 static int hf_amr_if1_sti = -1;
71 static int hf_amr_nb_if1_mode_ind = -1;
72 static int hf_amr_wb_if1_mode_ind = -1;
73 static int hf_amr_nb_if1_sti_mode_ind = -1;
74 static int hf_amr_wb_if1_sti_mode_ind = -1;
75 static int hf_amr_if2_sti = -1;
76 static int hf_amr_nb_if2_sti_mode_ind = -1;
77 static int hf_amr_wb_if2_sti_mode_ind = -1;
78
79 static int hf_amr_nb_if2_ft = -1;
80 static int hf_amr_wb_if2_ft = -1;
81
82
83 /* Initialize the subtree pointers */
84 static int ett_amr = -1;
85 static int ett_amr_toc = -1;
86
87 /* The dynamic payload type which will be dissected as AMR */
88
89 static guint temp_dynamic_payload_type = 0;
90 static gint amr_encoding_type = 0;
91 static gint amr_mode = AMR_NB;
92
93
94 /* Currently only octet aligned works */
95 /* static gboolean octet_aligned = TRUE; */
96
97 static const value_string amr_encoding_type_value[] = {
98         {0,             "RFC 3267"}, 
99         {1,             "RFC 3267 bandwidth-efficient mode"}, 
100         {2,             "AMR IF 1"},
101         {3,             "AMR IF 2"},
102         { 0,    NULL }
103 };
104
105
106 /* Table 1a of 3GPP TS 26.201*/
107 static const value_string amr_nb_codec_mode_vals[] = {
108         {0,             "AMR 4,75 kbit/s"}, 
109         {1,             "AMR 5,15 kbit/s"},
110         {2,             "AMR 5,90 kbit/s"},
111         {3,             "AMR 6,70 kbit/s (PDC-EFR)"},
112         {4,             "AMR 7,40 kbit/s (TDMA-EFR)"},
113         {5,             "AMR 7,95 kbit/s"},
114         {6,             "AMR 10,2 kbit/s"},
115         {7,             "AMR 12,2 kbit/s (GSM-EFR)"},
116         {AMR_NB_SID,    "AMR SID (Comfort Noise Frame)"},
117         {9,                             "GSM-EFR SID"},
118         {10,                    "TDMA-EFR SID "},
119         {11,                    "PDC-EFR SID"},
120         {12,                    "Illegal Frametype - for future use"},
121         {13,                    "Illegal Frametype - for future use"},
122         {14,                    "Illegal Frametype - for future use"},
123         {AMR_NO_TRANS,  "No Data (No transmission/No reception)"},
124         { 0,    NULL }
125 };
126
127 static const value_string amr_wb_codec_mode_vals[] = {
128         {0,                     "AMR-WB 6.60 kbit/s"},
129         {1,                     "AMR-WB 8.85 kbit/s"},
130         {2,                     "AMR-WB 12.65 kbit/s"},
131         {3,                     "AMR-WB 14.25 kbit/s"},
132         {4,                     "AMR-WB 15.85 kbit/s"},
133         {5,                     "AMR-WB 18.25 kbit/s"},
134         {6,                     "AMR-WB 19.85 kbit/s"},
135         {7,                     "AMR-WB 23.05 kbit/s"},
136         {8,                     "AMR-WB 23.85 kbit/s"},
137         {AMR_WB_SID,    "AMR-WB SID (Comfort Noise Frame)"},
138         {10,                    "Illegal Frametype"},
139         {11,                    "Illegal Frametype"},
140         {12,                    "Illegal Frametype"},
141         {13,                    "Illegal Frametype"},
142         {14,                    "Speech lost"},
143         {AMR_NO_TRANS,  "No Data (No transmission/No reception)"},
144         { 0,    NULL }
145 };
146
147 /* Ref 3GPP TS 26.101 table 1a for AMR-NB*/
148
149 /* From RFC3267 chapter 4.3.1 
150 CMR (4 bits): Indicates a codec mode request sent to the speech
151       encoder at the site of the receiver of this payload.  The value of
152       the CMR field is set to the frame type index of the corresponding
153       speech mode being requested.  The frame type index may be 0-7 for
154       AMR, as defined in Table 1a in [2], or 0-8 for AMR-WB, as defined
155       in Table 1a in [3GPP TS 26.201].  CMR value 15 indicates that no 
156       mode request is present, and other values are for future use.
157 */
158 static const value_string amr_nb_codec_mode_request_vals[] = {
159         {0,             "AMR 4,75 kbit/s"},
160         {1,             "AMR 5,15 kbit/s"},
161         {2,             "AMR 5,90 kbit/s"},
162         {3,             "AMR 6,70 kbit/s (PDC-EFR)"},
163         {4,             "AMR 7,40 kbit/s (TDMA-EFR)"},
164         {5,             "AMR 7,95 kbit/s"},
165         {6,             "AMR 10,2 kbit/s"},
166         {7,             "AMR 12,2 kbit/s (GSM-EFR)"},
167         {8,             "Illegal Frametype - For future use"},
168         {8,             "Illegal Frametype - For future use"},
169         {10,    "Illegal Frametype - For future use"},
170         {11,    "Illegal Frametype - For future use"},
171         {12,    "Illegal Frametype - For future use"},
172         {13,    "Illegal Frametype - For future use"},
173         {14,    "Illegal Frametype - For future use"},
174         {15,    "No mode request"}, 
175         { 0,    NULL }
176 };
177
178 /* Ref 3GPP TS 26.201 table 1a for AMR-WB*/
179 static const value_string amr_wb_codec_mode_request_vals[] = {
180         {0,             "AMR-WB 6.60 kbit/s"},
181         {1,             "AMR-WB 8.85 kbit/s"},
182         {2,             "AMR-WB 12.65 kbit/s"},
183         {3,             "AMR-WB 14.25 kbit/s"},
184         {4,             "AMR-WB 15.85 kbit/s"},
185         {5,             "AMR-WB 18.25 kbit/s"},
186         {6,             "AMR-WB 19.85 kbit/s"},
187         {7,             "AMR-WB 23.05 kbit/s"},
188         {8,             "AMR-WB 23.85 kbit/s"},
189         {9,             "Illegal Frametype - For future use"},
190         {10,            "Illegal Frametype - For future use"},
191         {11,            "Illegal Frametype - For future use"},
192         {12,            "Illegal Frametype - For future use"},
193         {13,            "Illegal Frametype - For future use"},
194         {14,            "Illegal Frametype - For future use"},
195         {15,            "No mode request"}, 
196         { 0,    NULL }
197 };
198
199 static const true_false_string toc_f_bit_vals = {
200   "Followed by another speech frame",
201   "Last frame in this payload"
202 };
203
204 static const true_false_string toc_q_bit_vals = {
205   "Ok",
206   "Severely damaged frame"
207 };
208
209 static const true_false_string amr_sti_vals = {
210   "SID_UPDATE",
211   "SID_FIRST"
212 };
213
214 /* See 3GPP TS 26.101 chapter 4 for AMR-NB IF1 */
215 static void
216 dissect_amr_nb_if1(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree){
217         int offset = 0;
218         guint8 octet;
219
220         proto_tree_add_item(tree, hf_amr_nb_if1_ft, tvb, offset, 1, FALSE);
221         proto_tree_add_item(tree, hf_amr_if1_fqi, tvb, offset, 1, FALSE);
222         octet = (tvb_get_guint8(tvb,offset) & 0xf0) >> 4;
223         if (octet == AMR_NB_SID){
224                 proto_tree_add_item(tree, hf_amr_nb_if1_mode_req, tvb, offset+1, 1, FALSE);
225                 if (tvb_get_guint8(tvb,offset+1) & 0x1f)
226                         proto_tree_add_text(tree, tvb, offset+1, 1, "Error:Spare bits not 0");
227                 proto_tree_add_text(tree, tvb, offset+2, 5, "Speech data");
228                 proto_tree_add_item(tree, hf_amr_if1_sti, tvb, offset+7, 1, FALSE);
229                 proto_tree_add_item(tree, hf_amr_nb_if1_sti_mode_ind, tvb, offset+7, 1, FALSE);
230                 return;
231         }
232
233         proto_tree_add_item(tree, hf_amr_nb_if1_mode_ind, tvb, offset, 1, FALSE);
234         offset++;
235         proto_tree_add_item(tree, hf_amr_nb_if1_mode_req, tvb, offset, 1, FALSE);
236         if (tvb_get_guint8(tvb,offset) & 0x1f)
237                 proto_tree_add_text(tree, tvb, offset, 1, "Error:Spare bits not 0");
238         offset++;
239         proto_tree_add_text(tree, tvb, offset, -1, "Speech data");
240
241 }
242
243 /* See 3GPP TS 26.201 for AMR-WB */
244 static void
245 dissect_amr_wb_if1(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree){
246         int offset = 0;
247         guint8 octet;
248         proto_tree_add_item(tree, hf_amr_wb_if1_ft, tvb, offset, 1, FALSE);
249         proto_tree_add_item(tree, hf_amr_if1_fqi, tvb, offset, 1, FALSE);
250         if (tvb_get_guint8(tvb,offset) & 0x03)
251                 proto_tree_add_text(tree, tvb, offset, 1, "Error:Spare bits not 0");
252         octet = (tvb_get_guint8(tvb,offset) & 0xf0) >> 4;
253         if (octet == AMR_WB_SID){
254                 proto_tree_add_item(tree, hf_amr_wb_if1_mode_req, tvb, offset+1, 1, FALSE);
255                 proto_tree_add_text(tree, tvb, offset+2, 4, "Speech data");
256                 proto_tree_add_item(tree, hf_amr_if1_sti, tvb, offset+7, 1, FALSE);
257                 proto_tree_add_item(tree, hf_amr_wb_if1_sti_mode_ind, tvb, offset+7, 1, FALSE);
258                 return;
259         }
260
261         offset++;
262         proto_tree_add_item(tree, hf_amr_wb_if1_mode_ind, tvb, offset, 1, FALSE);
263         proto_tree_add_item(tree, hf_amr_wb_if1_mode_req, tvb, offset, 1, FALSE);
264         offset++;
265         proto_tree_add_text(tree, tvb, offset, -1, "Speech data");
266
267
268 }
269
270 static void
271 dissect_amr_nb_if2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree){
272         int offset = 0;
273         guint8 octet;
274         
275         proto_tree_add_item(tree, hf_amr_nb_if2_ft, tvb, offset, 1, FALSE);
276         octet = tvb_get_guint8(tvb,offset) & 0x0f;
277         
278         if (octet == AMR_NB_SID) {
279                 proto_tree_add_text(tree, tvb, offset+1, 3, "Speech data");
280                 proto_tree_add_item(tree, hf_amr_if2_sti, tvb, offset+4, 1, FALSE);
281                 proto_tree_add_item(tree, hf_amr_nb_if2_sti_mode_ind, tvb, offset+5, 1, FALSE);
282                 return;
283         }
284         if (octet == AMR_NO_TRANS)
285                 return;
286         proto_tree_add_text(tree, tvb, offset+1, -1, "Speech data");
287
288         if(check_col(pinfo->cinfo, COL_INFO))
289                 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
290                                 val_to_str(octet, amr_nb_codec_mode_request_vals, "Unknown (%d)" ));
291 }
292
293 static void
294 dissect_amr_wb_if2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree){
295         int offset = 0;
296         guint8 octet;
297         
298         proto_tree_add_item(tree, hf_amr_wb_if2_ft, tvb, offset, 1, FALSE);
299         octet = (tvb_get_guint8(tvb,offset) & 0xf0) >> 4;
300         
301         if (octet == AMR_WB_SID) {
302                 proto_tree_add_text(tree, tvb, offset+1, 4, "Speech data");
303                 proto_tree_add_item(tree, hf_amr_if2_sti, tvb, offset+5, 1, FALSE);
304                 proto_tree_add_item(tree, hf_amr_wb_if2_sti_mode_ind, tvb, offset+5, 1, FALSE);
305                 return;
306         }
307         if (octet == AMR_NO_TRANS)
308                 return;
309         proto_tree_add_text(tree, tvb, offset+1, -1, "Speech data");
310
311         if(check_col(pinfo->cinfo, COL_INFO))
312                 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
313                                 val_to_str(octet, amr_wb_codec_mode_request_vals, "Unknown (%d)" ));
314 }
315
316 static void
317 dissect_amr_be(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree){
318         proto_item *item;
319         int ft;
320         int bit_offset = 0;
321         int bitcount; /*bitcounter, MSB = bit 0, over bytes*/
322         int bits_used_for_frames = 0;
323         int bytes_needed_for_frames;
324         guint8 f_bit, q_bit;
325         
326         /* Number of bits per frame for AMR-NB, see Table 1 RFC3267*/
327         /* Values taken for GSM-EFR SID, TDMA-EFR SID and PDC-EFR SID from 3GPP 26.101 Table A.1b */
328
329         /*               Frame type     0   1   2   3   4   5   6   7  8  9  10 11 12 13 14 15 */
330         unsigned char Framebits_NB[] = {95,103,118,134,148,159,204,244,39,43,38,37, 0, 0, 0, 0};
331         
332         /* Number of bits per frame for AMR-WB, see 3GPP TS 26.201 Table 2*/
333         /*               Frame type     0   1   2   3   4   5   6   7   8   9  10 11 12 13 14 15 */
334         unsigned int Framebits_WB[] = {132,177,253,285,317,365,397,461,477,40,0, 0, 0, 0, 0, 0,};
335
336         
337         /* Chapter 4.3 */
338
339         bitcount = 3;
340         if (amr_mode==AMR_NB)
341                 item = proto_tree_add_bits_item(tree, hf_amr_nb_cmr, tvb, bit_offset, 4, FALSE);
342         else    
343                 item = proto_tree_add_bits_item(tree, hf_amr_wb_cmr, tvb, bit_offset, 4, FALSE);        
344             
345         bit_offset+=4;
346         /* In bandwidth-efficient mode, a ToC entry takes the following format:
347          *
348          *    0 1 2 3 4 5
349          *   +-+-+-+-+-+-+
350          *   |F|  FT   |Q|
351          *   +-+-+-+-+-+-+
352          *
353          *   F (1 bit): If set to 1, indicates that this frame is followed by
354          *      another speech frame in this payload; if set to 0, indicates that
355          *      this frame is the last frame in this payload.
356          *
357          *   FT (4 bits): Frame type index, indicating either the AMR or AMR-WB
358          *      speech coding mode or comfort noise (SID) mode of the
359          *      corresponding frame carried in this payload.
360          */
361         do {
362                 /* Check F bit */
363                 bitcount += 1;
364                 f_bit = tvb_get_bits8(tvb, bit_offset, 1);
365                 proto_tree_add_bits_item(tree, hf_amr_toc_f, tvb, bit_offset, 1, FALSE);
366                 bit_offset++;
367                 ft = tvb_get_bits8(tvb, bit_offset, 4);
368                 if (amr_mode==AMR_NB)
369                         item = proto_tree_add_bits_item(tree, hf_amr_nb_toc_ft, tvb, bit_offset, 4, FALSE);
370                 else
371                         item = proto_tree_add_bits_item(tree, hf_amr_wb_toc_ft, tvb, bit_offset, 4, FALSE);
372                             
373                 bit_offset+=4;
374                 bitcount += 4;
375                 if (amr_mode==AMR_NB)
376                         bits_used_for_frames +=Framebits_NB[ft];
377                 else    
378                         bits_used_for_frames +=Framebits_WB[ft];
379                 /* Check Q bit */
380                 q_bit = tvb_get_bits8(tvb, bit_offset, 1);
381                 proto_tree_add_bits_item(tree, hf_amr_toc_q, tvb, bit_offset, 1, FALSE);
382                 bit_offset++;
383                 bitcount += 1;
384                 if (q_bit==1)
385                         proto_item_append_text(item, " / Frame OK");
386                 else    
387                         proto_item_append_text(item, " / Frame damaged");
388         } while ((f_bit==1) && (tvb_reported_length_remaining(tvb, bitcount/8)>2));
389         
390         if (bits_used_for_frames>0)
391                 bytes_needed_for_frames = 1 + (bitcount+bits_used_for_frames)/8-bitcount/8;
392         else     
393                 bytes_needed_for_frames = 0;
394
395         /* Check if we have enough data available for our frames */    
396         if (tvb_reported_length_remaining(tvb, bitcount/8)<bytes_needed_for_frames)     {
397                 item = proto_tree_add_text(tree, tvb, bitcount/8, bytes_needed_for_frames, "Error:");
398                 proto_item_append_text(item, " %d Bytes available, %d would be needed!",
399                                        tvb_reported_length_remaining(tvb, bitcount/8),
400                                        bytes_needed_for_frames);
401                 expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "Not enough data for the frames according to TOC");
402         }                           
403         else {
404                 item = proto_tree_add_text(tree, tvb, bitcount/8, bytes_needed_for_frames, "Frame Data");
405                 proto_item_append_text(item, " (%d Bytes)",bytes_needed_for_frames);
406         }    
407         
408         bitcount+=bits_used_for_frames;
409         
410         if (tvb_reported_length_remaining(tvb, (bitcount+8)/8)>0)       {
411                 item = proto_tree_add_text(tree, tvb, bitcount/8, tvb_reported_length_remaining(tvb, bitcount/8), "Error:");
412                 proto_item_append_text(item, " %d Bytes remaining - should be 0!",tvb_reported_length_remaining(tvb, (bitcount+8)/8));
413                 expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "Superfluous data remaining");
414
415                 /* Now check the paddings */
416                 if (bitcount%8 != 0)    {
417                         if ( (1 << (8 -(bitcount%8)-1)) & tvb_get_guint8(tvb,bitcount/8) )
418                                 item = proto_tree_add_text(tree, tvb, bitcount/8, 1, "Padding bits correct");
419                         else    {
420                                 item = proto_tree_add_text(tree, tvb, bitcount/8, 1, "Padding bits error");
421                                 expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "Padding bits error - MUST be 0");
422                         }    
423
424                 }           
425         }    
426         
427 }
428 /* Code to actually dissect the packets */
429 static void
430 dissect_amr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
431 {
432         int offset = 0;
433         int bit_offset = 0;
434         int toc_offset = 0;
435         guint8 octet;
436         proto_item *item;
437         gboolean first_time;
438
439 /* Set up structures needed to add the protocol subtree and manage it */
440         proto_item *ti,*toc_item;
441         proto_tree *amr_tree, *toc_tree;
442
443 /* Make entries in Protocol column and Info column on summary display */
444         col_set_str(pinfo->cinfo, COL_PROTOCOL, "AMR");
445         if (tree) {
446
447                 ti = proto_tree_add_item(tree, proto_amr, tvb, 0, -1, FALSE);
448                 amr_tree = proto_item_add_subtree(ti, ett_amr);
449
450                 proto_tree_add_text(amr_tree, tvb, offset, -1, "Payload decoded as %s",
451                     val_to_str(amr_encoding_type, amr_encoding_type_value, "Unknown value - Error"));
452
453                 switch (amr_encoding_type){
454                 case 0: /* RFC 3267 Byte aligned */
455                         break;
456                 case 1: /* RFC 3267 Bandwidth-efficient */
457                         dissect_amr_be(tvb, pinfo, amr_tree);
458                         return;
459                 case 2: /* AMR IF1 */
460                         if (amr_mode==AMR_NB)
461                             dissect_amr_nb_if1(tvb, pinfo, amr_tree);
462                         else
463                             dissect_amr_wb_if1(tvb, pinfo, amr_tree);    
464                         return;
465                 case 3: /* AMR IF2 */
466                         if (amr_mode==AMR_NB)
467                             dissect_amr_nb_if2(tvb, pinfo, amr_tree);
468                         else
469                             dissect_amr_wb_if2(tvb, pinfo, amr_tree);    
470                         return;
471                 default:
472                         break;
473                 }
474                 
475                 if (amr_mode==AMR_NB)
476                         proto_tree_add_bits_item(amr_tree, hf_amr_nb_cmr, tvb, bit_offset, 4, FALSE);
477                 else
478                         proto_tree_add_bits_item(amr_tree, hf_amr_wb_cmr, tvb, bit_offset, 4, FALSE);
479                     
480                 bit_offset+=4;
481                 octet = tvb_get_guint8(tvb,offset) & 0x0f;
482                 if ( octet != 0  ){
483                         item = proto_tree_add_text(amr_tree, tvb, offset, -1, "Reserved != 0, wrongly encoded or not octet aligned. Decoding as bandwidth-efficient mode");
484                         PROTO_ITEM_SET_GENERATED(item);
485                         return;
486
487                 }
488
489                 proto_tree_add_item(amr_tree, hf_amr_reserved, tvb, offset, 1, FALSE);
490                 offset++;
491                 bit_offset+=4;
492                 toc_offset = offset;
493                 /*
494                  *  A ToC entry takes the following format in octet-aligned mode:
495                  *
496                  *    0 1 2 3 4 5 6 7
497                  *   +-+-+-+-+-+-+-+-+
498                  *   |F|  FT   |Q|P|P|
499                  *   +-+-+-+-+-+-+-+-+
500                  *
501                  *   F (1 bit): see definition in Section 4.3.2.
502                  *
503                  *   FT (4 bits unsigned integer): see definition in Section 4.3.2.
504                  *
505                  *   Q (1 bit): see definition in Section 4.3.2.
506                  *
507                  *   P bits: padding bits, MUST be set to zero.
508                  */
509                 octet = tvb_get_guint8(tvb,offset);
510                 toc_item = proto_tree_add_text(amr_tree, tvb, offset, -1, "Payload Table of Contents");
511                 toc_tree = proto_item_add_subtree(toc_item, ett_amr_toc);
512                 
513                 first_time = TRUE;
514                 while ((( octet& 0x80 ) == 0x80)||(first_time == TRUE)){
515                         first_time = FALSE;
516                         octet = tvb_get_guint8(tvb,offset);     
517                         
518                         proto_tree_add_bits_item(amr_tree, hf_amr_toc_f, tvb, bit_offset, 1, FALSE);
519                         bit_offset++;
520                         if (amr_mode==AMR_NB)
521                                 proto_tree_add_bits_item(amr_tree, hf_amr_nb_toc_ft, tvb, bit_offset, 4, FALSE);
522                         else
523                                 proto_tree_add_bits_item(amr_tree, hf_amr_wb_toc_ft, tvb, bit_offset, 4, FALSE);
524                         bit_offset+=4;
525                         proto_tree_add_bits_item(amr_tree, hf_amr_toc_q, tvb, bit_offset, 1, FALSE);
526                         bit_offset++;
527                         /* 2 pading bits */
528                         bit_offset+=2;
529                         offset++;
530                 }
531
532         }/* if tree */
533
534 }
535
536 typedef struct _amr_capability_t {
537   const gchar *id;
538   const gchar *name;
539   new_dissector_t content_pdu;
540 } amr_capability_t;
541
542 static amr_capability_t amr_capability_tab[] = {
543   /* ITU-T H.241 (05/2006), 8.3 H.264 capabilities */
544   { "GenericCapability/0.0.8.245.1.1.1", "H.245 - GSM AMR Capability Identifier", NULL },
545   { "GenericCapability/0.0.8.245.1.1.1/collapsing/0", "maxAl-sduAudioFrames", NULL },
546   { "GenericCapability/0.0.8.245.1.1.1/collapsing/1", "bitRate", NULL },
547   { "GenericCapability/0.0.8.245.1.1.1/collapsing/2", "gsmAmrComfortNoise", NULL },
548   { "GenericCapability/0.0.8.245.1.1.1/collapsing/3", "gsmEfrComfortNoise", NULL },
549   { "GenericCapability/0.0.8.245.1.1.1/collapsing/4", "is-641ComfortNoise", NULL },
550   { "GenericCapability/0.0.8.245.1.1.1/collapsing/5", "pdcEFRComfortNoise", NULL },
551   /* ITU-T Rec. G.722.2/Annex F (11/2002) */
552   { "GenericCapability/0.0.7.7222.1.0/collapsing/0", "maxAl-sduFrames", NULL },
553   { "GenericCapability/0.0.7.7222.1.0/collapsing/1", "bitRate", NULL },
554   { "GenericCapability/0.0.7.7222.1.0/collapsing/2", "octetAlign", NULL },
555   { "GenericCapability/0.0.7.7222.1.0/collapsing/3", "modeSet", NULL },
556   { "GenericCapability/0.0.7.7222.1.0/collapsing/4", "modeChangePeriod", NULL },
557   { "GenericCapability/0.0.7.7222.1.0/collapsing/5", "modeChangeNeighbour", NULL },
558   { "GenericCapability/0.0.7.7222.1.0/collapsing/6", "crc", NULL },
559   { "GenericCapability/0.0.7.7222.1.0/collapsing/7", "robustSorting", NULL },
560   { "GenericCapability/0.0.7.7222.1.0/collapsing/8", "interleaving", NULL },
561   { NULL, NULL, NULL },
562 };      
563
564 static amr_capability_t *find_cap(const gchar *id) {
565         amr_capability_t *ftr = NULL;
566         amr_capability_t *f;
567
568         for (f=amr_capability_tab; f->id; f++) {
569                 if (!strcmp(id, f->id)) { ftr = f; break; }
570         }
571         return ftr;
572 }
573
574 static void
575 dissect_amr_name(tvbuff_t *tvb _U_, packet_info *pinfo, proto_tree *tree) 
576 {
577         asn1_ctx_t *actx;
578         amr_capability_t *ftr = NULL; 
579
580         actx = get_asn1_ctx(pinfo->private_data);
581         DISSECTOR_ASSERT(actx);
582         if (tree) {
583                 ftr = find_cap(pinfo->match_string);
584                 if (ftr) {
585                         proto_item_append_text(actx->created_item, " - %s", ftr->name);
586                         proto_item_append_text(proto_item_get_parent(proto_tree_get_parent(tree)), ": %s", ftr->name);
587                 } else {
588                         proto_item_append_text(actx->created_item, " - unknown(%s)", pinfo->match_string);
589                 }
590         }
591 }
592
593 /* Register the protocol with Wireshark */
594 /* If this dissector uses sub-dissector registration add a registration routine.
595    This format is required because a script is used to find these routines and
596    create the code that calls these routines.
597 */
598 void
599 proto_reg_handoff_amr(void)
600 {
601         static dissector_handle_t amr_handle;
602         static guint dynamic_payload_type;
603         static gboolean amr_prefs_initialized = FALSE;
604
605         if (!amr_prefs_initialized) {
606                 dissector_handle_t amr_name_handle;
607                 amr_capability_t *ftr; 
608
609                 amr_handle = find_dissector("amr");
610                 dissector_add_string("rtp_dyn_payload_type","AMR", amr_handle);
611
612                 /* 
613                  * Register H.245 Generic parameter name(s)
614                  */
615                 amr_name_handle = create_dissector_handle(dissect_amr_name, proto_amr);
616                 for (ftr=amr_capability_tab; ftr->id; ftr++) {
617                         if (ftr->name) 
618                                 dissector_add_string("h245.gef.name", ftr->id, amr_name_handle);
619                         if (ftr->content_pdu)
620                                 dissector_add_string("h245.gef.content", ftr->id, new_create_dissector_handle(ftr->content_pdu, proto_amr));
621                 }
622                 /*      Activate the next line for testing with the randpkt tool
623                         dissector_add("udp.port", 55555, amr_handle); 
624                 */
625                 amr_prefs_initialized = TRUE;
626         } else {
627                 if ( dynamic_payload_type > 95 )
628                         dissector_delete("rtp.pt", dynamic_payload_type, amr_handle);
629         }
630
631         dynamic_payload_type = temp_dynamic_payload_type;
632
633         if ( dynamic_payload_type > 95 ){
634                 dissector_add("rtp.pt", dynamic_payload_type, amr_handle);
635         }
636         
637 }
638
639 /* this format is require because a script is used to build the C function
640    that calls all the protocol registration.
641 */
642
643 void
644 proto_register_amr(void)
645 {                 
646
647         module_t *amr_module;
648
649  /* Setup list of header fields  See Section 1.6.1 for details*/
650         static hf_register_info hf[] = {
651                 { &hf_amr_nb_cmr,
652                         { "CMR",           "amr.nb.cmr",
653                         FT_UINT8, BASE_DEC, VALS(amr_nb_codec_mode_request_vals), 0x0,          
654                         "codec mode request", HFILL }
655                 },
656                 { &hf_amr_wb_cmr,
657                         { "CMR",           "amr.wb.cmr",
658                         FT_UINT8, BASE_DEC, VALS(amr_wb_codec_mode_request_vals), 0x0,          
659                         "codec mode request", HFILL }
660                 },
661                 { &hf_amr_reserved,
662                         { "Reserved",           "amr.reserved",
663                         FT_UINT8, BASE_DEC, NULL, 0x0f,          
664                         "Reserved bits", HFILL }
665                 },
666                 { &hf_amr_toc_f,
667                         { "F bit",           "amr.toc.f",
668                         FT_BOOLEAN, BASE_NONE, TFS(&toc_f_bit_vals), 0x0,          
669                         NULL, HFILL }
670                 },
671                 { &hf_amr_nb_toc_ft,
672                         { "FT bits",           "amr.nb.toc.ft",
673                         FT_UINT8, BASE_DEC, VALS(amr_nb_codec_mode_request_vals), 0x0,          
674                         "Frame type index", HFILL }
675                 },
676                 { &hf_amr_wb_toc_ft,
677                         { "FT bits",           "amr.wb.toc.ft",
678                         FT_UINT8, BASE_DEC, VALS(amr_wb_codec_mode_request_vals), 0x0,          
679                         "Frame type index", HFILL }
680                 },
681                 { &hf_amr_toc_q,
682                         { "Q bit",           "amr.toc.q",
683                         FT_BOOLEAN, BASE_NONE, TFS(&toc_q_bit_vals), 0x0,          
684                         "Frame quality indicator bit", HFILL }
685                 },
686                 { &hf_amr_nb_if1_ft,
687                         { "Frame Type",           "amr.nb.if1.ft",
688                         FT_UINT8, BASE_DEC, VALS(amr_nb_codec_mode_vals), 0xf0,          
689                         NULL, HFILL }
690                 },
691                 { &hf_amr_wb_if1_ft,
692                         { "Frame Type",           "amr.wb.if1.ft",
693                         FT_UINT8, BASE_DEC, VALS(amr_wb_codec_mode_vals), 0xf0,          
694                         NULL, HFILL }
695                 },
696                 { &hf_amr_nb_if1_mode_req,
697                         { "Mode Type request",           "amr.nb.if1.modereq",
698                         FT_UINT8, BASE_DEC, VALS(amr_nb_codec_mode_request_vals), 0xe0,
699                         NULL, HFILL }
700                 },
701                 { &hf_amr_wb_if1_mode_req,
702                         { "Mode Type request",           "amr.wb.if1.modereq",
703                         FT_UINT8, BASE_DEC, VALS(amr_wb_codec_mode_request_vals), 0x0f,
704                         NULL, HFILL }
705                 },
706                 { &hf_amr_if1_sti,
707                         { "SID Type Indicator",           "amr.if1.sti",
708                         FT_BOOLEAN, 8, TFS(&amr_sti_vals), 0x10,          
709                         NULL, HFILL }
710                 },
711                 { &hf_amr_nb_if1_sti_mode_ind,
712                         { "Mode Type indication",           "amr.nb.if1.stimodeind",
713                         FT_UINT8, BASE_DEC, VALS(amr_nb_codec_mode_vals), 0x0e,
714                         NULL, HFILL }
715                 },
716                 { &hf_amr_wb_if1_sti_mode_ind,
717                         { "Mode Type indication",           "amr.wb.if1.stimodeind",
718                         FT_UINT8, BASE_DEC, VALS(amr_wb_codec_mode_vals), 0x0f,
719                         NULL, HFILL }
720                 },
721                 { &hf_amr_nb_if1_mode_ind,
722                         { "Mode Type indication",           "amr.nb.if1.modeind",
723                         FT_UINT8, BASE_DEC, VALS(amr_nb_codec_mode_vals), 0x07,
724                         NULL, HFILL }
725                 },
726                 { &hf_amr_wb_if1_mode_ind,
727                         { "Mode Type indication",           "amr.wb.if1.modeind",
728                         FT_UINT8, BASE_DEC, VALS(amr_wb_codec_mode_vals), 0xf0,
729                         NULL, HFILL }
730                 },
731                 { &hf_amr_nb_if2_ft,
732                         { "Frame Type",           "amr.nb.if2.ft",
733                         FT_UINT8, BASE_DEC, VALS(amr_nb_codec_mode_vals), 0x0f,
734                         NULL, HFILL }
735                 },
736                 { &hf_amr_wb_if2_ft,
737                         { "Frame Type",           "amr.wb.if2.ft",
738                         FT_UINT8, BASE_DEC, VALS(amr_wb_codec_mode_vals), 0xf0,
739                         NULL, HFILL }
740                 },
741                 { &hf_amr_if2_sti,
742                         { "SID Type Indicator",           "amr.if2.sti",
743                         FT_BOOLEAN, 8, TFS(&amr_sti_vals), 0x80,          
744                         NULL, HFILL }
745                 },
746                 { &hf_amr_nb_if2_sti_mode_ind,
747                         { "Mode Type indication",           "amr.nb.if2.stimodeind",
748                         FT_UINT8, BASE_DEC, VALS(amr_nb_codec_mode_vals), 0x07,
749                         NULL, HFILL }
750                 },
751                 { &hf_amr_wb_if2_sti_mode_ind,
752                         { "Mode Type indication",           "amr.wb.if2.stimodeind",
753                         FT_UINT8, BASE_DEC, VALS(amr_wb_codec_mode_vals), 0x78,
754                         NULL, HFILL }
755                 },
756                 { &hf_amr_if1_fqi,
757                         { "FQI",           "amr.fqi",
758                         FT_BOOLEAN, 8, TFS(&toc_q_bit_vals), 0x08,          
759                         "Frame quality indicator bit", HFILL }
760                 },
761         };
762
763 /* Setup protocol subtree array */
764         static gint *ett[] = {
765                 &ett_amr,
766                 &ett_amr_toc,
767         };
768         static enum_val_t encoding_types[] = {
769                 {"RFC 3267 Byte aligned", "RFC 3267 octet aligned", 0},
770                 {"RFC 3267 Bandwidth-efficient", "RFC 3267 BW-efficient", 1}, 
771                 {"AMR IF1", "AMR IF1", 2},
772                 {"AMR IF2", "AMR IF2", 3},
773                 {NULL, NULL, -1}
774         };
775
776         static enum_val_t modes[] = {
777                 {"AMR-NB", "Narrowband AMR", AMR_NB},
778                 {"AMR-WB", "Wideband AMR", AMR_WB}, 
779                 {NULL, NULL, -1}
780         };
781
782 /* Register the protocol name and description */
783         proto_amr = proto_register_protocol("Adaptive Multi-Rate","AMR", "amr");
784
785 /* Required function calls to register the header fields and subtrees used */
786         proto_register_field_array(proto_amr, hf, array_length(hf));
787         proto_register_subtree_array(ett, array_length(ett));
788         /* Register a configuration option for port */
789         
790         amr_module = prefs_register_protocol(proto_amr, proto_reg_handoff_amr);
791
792         prefs_register_uint_preference(amr_module, "dynamic.payload.type",
793                                        "AMR dynamic payload type",
794                                        "The dynamic payload type which will be interpreted as AMR" 
795                                        "; The value must be greater than 95",
796                                        10,
797                                        &temp_dynamic_payload_type);
798
799         prefs_register_enum_preference(amr_module, "encoding.version",
800                                        "Type of AMR encoding of the payload",
801                                        "Type of AMR encoding of the payload",
802                                        &amr_encoding_type, encoding_types, FALSE);
803
804         prefs_register_enum_preference(amr_module, "mode",
805                                        "The AMR mode",
806                                        "The AMR mode",
807                                        &amr_mode, modes, AMR_NB);
808         
809         register_dissector("amr", dissect_amr, proto_amr);
810         register_dissector("amr_if1_nb", dissect_amr_nb_if1, proto_amr);
811         register_dissector("amr_if1_wb", dissect_amr_wb_if1, proto_amr);
812         register_dissector("amr_if2_nb", dissect_amr_nb_if2, proto_amr);
813         register_dissector("amr_if2_wb", dissect_amr_wb_if2, proto_amr);
814
815         oid_add_from_string("G.722.2 (AMR-WB) audio capability","0.0.7.7222.1.0");
816         
817
818 }