Coverage Report

Created: 2026-07-12 07:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-mrcpv2.c
Line
Count
Source
1
/* packet-mrcpv2.c
2
 * Routines for Media Resource Control Protocol Version 2 (MRCPv2) dissection
3
 * Copyright 2012, Zeljko Ancimer  <zancimer[AT]gmail.com>
4
 *
5
 * Wireshark - Network traffic analyzer
6
 * By Gerald Combs <gerald@wireshark.org>
7
 * Copyright 1998 Gerald Combs
8
 *
9
 * SPDX-License-Identifier: GPL-2.0-or-later
10
 */
11
/*
12
 * Based on RFC 6787
13
 *
14
 * TODO:
15
 * - TLS has not been tested
16
 * - MRCP conversation (similar to VoIP Calls)
17
 * - convert header value into the correct types (numbers, booleans,...);
18
 *   currently all values are treated as strings so one has to be
19
 *   careful with the usage of filters; to do this, one has to go through
20
 *   the mrcp draft and look for the definition of each header (see
21
 *   chapter titled "15. ABNF Normative Definition")
22
 */
23
#include "config.h"
24
25
/* Include only as needed */
26
#include <stdlib.h>
27
28
#include <epan/packet.h>
29
#include <epan/expert.h>
30
#include "packet-tcp.h"
31
32
#include <wsutil/str_util.h>
33
#include <wsutil/strtoi.h>
34
35
void proto_register_mrcpv2(void);
36
void proto_reg_handoff_mrcpv2(void);
37
38
static dissector_handle_t mrcpv2_handle;
39
40
/* mrcp-version SP message-length */
41
/*   mrcp-version = "MRCP" "/" 1*2DIGIT "." 1*2DIGIT  ==> up to 10 chars */
42
/*   SP ==> whitespace, 1 char */
43
/*   message-length = 1*19DIGIT  ==> up to 19 chars */
44
/*   total = 10 + 1 + 19 = 30 */
45
46
/* min length to determine MRCPv2 version */
47
104
#define MRCPV2_MIN_LENGTH    10
48
/* min length to determine MRCPv2 PDU length */
49
0
#define MRCPV2_MIN_PDU_LEN   30
50
51
/* line type */
52
typedef enum {
53
    REQUEST_LINE,
54
    RESPONSE_LINE,
55
    EVENT_LINE,
56
    UNKNOWN_LINE
57
} LINE_TYPE;
58
59
/* header type */
60
typedef enum {
61
    UNKNOWN =                               0,
62
    ABORT_MODEL =                           1,
63
    ABORT_PHRASE_ENROLLMENT =               2,
64
    ABORT_VERIFICATION =                    3,
65
    ACCEPT =                                4,
66
    ACCEPT_CHARSET =                        5,
67
    ACTIVE_REQUEST_ID_LIST =                6,
68
    ADAPT_MODEL =                           7,
69
    AUDIO_FETCH_HINT =                      8,
70
    CACHE_CONTROL =                         9,
71
    CANCEL_IF_QUEUE =                       10,
72
    CAPTURE_ON_SPEECH =                     11,
73
    CHANNEL_IDENTIFIER =                    12,
74
    CLASH_THRESHOLD =                       13,
75
    CLEAR_DTMF_BUFFER =                     14,
76
    COMPLETION_CAUSE =                      15,
77
    COMPLETION_REASON =                     16,
78
    CONFIDENCE_THRESHOLD =                  17,
79
    CONFUSABLE_PHRASES_URI =                18,
80
    CONSISTENCY_THRESHOLD =                 19,
81
    CONTENT_BASE =                          20,
82
    CONTENT_ENCODING =                      21,
83
    CONTENT_ID =                            22,
84
    CONTENT_LENGTH =                        23,
85
    CONTENT_LOCATION =                      24,
86
    CONTENT_TYPE =                          25,
87
    DTMF_BUFFER_TIME =                      26,
88
    DTMF_INTERDIGIT_TIMEOUT =               27,
89
    DTMF_TERM_CHAR =                        28,
90
    DTMF_TERM_TIMEOUT =                     29,
91
    EARLY_NO_MATCH =                        30,
92
    ENROLL_UTTERANCE =                      31,
93
    FAILED_URI =                            32,
94
    FAILED_URI_CAUSE =                      33,
95
    FETCH_HINT =                            34,
96
    FETCH_TIMEOUT =                         35,
97
    FINAL_SILENCE =                         36,
98
    HOTWORD_MAX_DURATION =                  37,
99
    HOTWORD_MIN_DURATION =                  38,
100
    INPUT_TYPE =                            39,
101
    INPUT_WAVEFORM_URI =                    40,
102
    INTERPRET_TEXT =                        41,
103
    JUMP_SIZE =                             42,
104
    KILL_ON_BARGE_IN =                      43,
105
    LEXICON_SEARCH_ORDER =                  44,
106
    LOAD_LEXICON =                          45,
107
    LOGGING_TAG =                           46,
108
    MAX_TIME =                              47,
109
    MEDIA_TYPE =                            48,
110
    MIN_VERIFICATION_SCORE =                49,
111
    N_BEST_LIST_LENGTH =                    50,
112
    NEW_AUDIO_CHANNEL =                     51,
113
    NEW_PHRASE_ID =                         52,
114
    NO_INPUT_TIMEOUT =                      53,
115
    NUM_MAX_VERIFICATION_PHRASES =          54,
116
    NUM_MIN_CONSISTENT_PRONUNCIATIONS =     55,
117
    NUM_MIN_VERIFICATION_PHRASES =          56,
118
    PERSONAL_GRAMMAR_URI =                  57,
119
    PHRASE_ID =                             58,
120
    PHRASE_NL =                             59,
121
    PROSODY_CONTOUR =                       60,
122
    PROSODY_DURATION =                      61,
123
    PROSODY_PITCH =                         62,
124
    PROSODY_RANGE =                         63,
125
    PROSODY_RATE =                          64,
126
    PROSODY_VOLUME =                        65,
127
    PROXY_SYNC_ID =                         66,
128
    RECOGNITION_MODE =                      67,
129
    RECOGNITION_TIMEOUT =                   68,
130
    RECOGNIZER_CONTEXT_BLOCK =              69,
131
    RECORD_URI =                            70,
132
    REPOSITORY_URI =                        71,
133
    SAVE_BEST_WAVEFORM =                    72,
134
    SAVE_WAVEFORM =                         73,
135
    SENSITIVITY_LEVEL =                     74,
136
    SET_COOKIE =                            75,
137
    SPEAK_LENGTH =                          76,
138
    SPEAK_RESTART =                         77,
139
    SPEAKER_PROFILE =                       78,
140
    SPEECH_COMPLETE_TIMEOUT =               79,
141
    SPEECH_INCOMPLETE_TIMEOUT =             80,
142
    SPEECH_LANGUAGE =                       81,
143
    SPEECH_MARKER =                         82,
144
    SPEED_VS_ACCURACY =                     83,
145
    START_INPUT_TIMERS =                    84,
146
    TRIM_LENGTH =                           85,
147
    VENDOR_SPECIFIC_PARAMETERS =            86,
148
    VER_BUFFER_UTTERANCE =                  87,
149
    VERIFICATION_MODE =                     88,
150
    VOICE_AGE =                             89,
151
    VOICE_GENDER =                          90,
152
    VOICE_NAME =                            91,
153
    VOICE_VARIANT =                         92,
154
    VOICEPRINT_EXISTS =                     93,
155
    VOICEPRINT_IDENTIFIER =                 94,
156
    WAVEFORM_URI =                          95,
157
    WEIGHT =                                96
158
} HEADER_TYPE;
159
160
static const value_string header_type_vals[] = {
161
    { ABORT_MODEL,                          "abort-model" },
162
    { ABORT_PHRASE_ENROLLMENT,              "abort-phrase-enrollment" },
163
    { ABORT_VERIFICATION,                   "abort-verification" },
164
    { ACCEPT,                               "accept" },
165
    { ACCEPT_CHARSET,                       "accept-charset" },
166
    { ACTIVE_REQUEST_ID_LIST,               "active-request-id-list" },
167
    { ADAPT_MODEL,                          "adapt-model" },
168
    { AUDIO_FETCH_HINT,                     "audio-fetch-hint" },
169
    { CACHE_CONTROL,                        "cache-control" },
170
    { CANCEL_IF_QUEUE,                      "cancel-if-queue" },
171
    { CAPTURE_ON_SPEECH,                    "capture-on-speech" },
172
    { CHANNEL_IDENTIFIER,                   "channel-identifier" },
173
    { CLASH_THRESHOLD,                      "clash-threshold" },
174
    { CLEAR_DTMF_BUFFER,                    "clear-dtmf-buffer" },
175
    { COMPLETION_CAUSE,                     "completion-cause" },
176
    { COMPLETION_REASON,                    "completion-reason" },
177
    { CONFIDENCE_THRESHOLD,                 "confidence-threshold" },
178
    { CONFUSABLE_PHRASES_URI,               "confusable-phrases-uri" },
179
    { CONSISTENCY_THRESHOLD,                "consistency-threshold" },
180
    { CONTENT_BASE,                         "content-base" },
181
    { CONTENT_ENCODING,                     "content-encoding" },
182
    { CONTENT_ID,                           "content-id" },
183
    { CONTENT_LENGTH,                       "content-length" },
184
    { CONTENT_LOCATION,                     "content-location" },
185
    { CONTENT_TYPE,                         "content-type" },
186
    { DTMF_BUFFER_TIME,                     "dtmf-buffer-time" },
187
    { DTMF_INTERDIGIT_TIMEOUT,              "dtmf-interdigit-timeout" },
188
    { DTMF_TERM_CHAR,                       "dtmf-term-char" },
189
    { DTMF_TERM_TIMEOUT,                    "dtmf-term-timeout" },
190
    { EARLY_NO_MATCH,                       "early-no-match" },
191
    { ENROLL_UTTERANCE,                     "enroll-utterance" },
192
    { FAILED_URI,                           "failed-uri" },
193
    { FAILED_URI_CAUSE,                     "failed-uri-cause" },
194
    { FETCH_HINT,                           "fetch-hint" },
195
    { FETCH_TIMEOUT,                        "fetch-timeout" },
196
    { FINAL_SILENCE,                        "final-silence" },
197
    { HOTWORD_MAX_DURATION,                 "hotword-max-duration" },
198
    { HOTWORD_MIN_DURATION,                 "hotword-min-duration" },
199
    { INPUT_TYPE,                           "input-type" },
200
    { INPUT_WAVEFORM_URI,                   "input-waveform-uri" },
201
    { INTERPRET_TEXT,                       "interpret-text" },
202
    { JUMP_SIZE,                            "jump-size" },
203
    { KILL_ON_BARGE_IN,                     "kill-on-barge-in" },
204
    { LEXICON_SEARCH_ORDER,                 "lexicon-search-order" },
205
    { LOAD_LEXICON,                         "load-lexicon" },
206
    { LOGGING_TAG,                          "logging-tag" },
207
    { MAX_TIME,                             "max-time" },
208
    { MEDIA_TYPE,                           "media-type" },
209
    { MIN_VERIFICATION_SCORE,               "min-verification-score" },
210
    { N_BEST_LIST_LENGTH,                   "n-best-list-length" },
211
    { NEW_AUDIO_CHANNEL,                    "new-audio-channel" },
212
    { NEW_PHRASE_ID,                        "new-phrase-id" },
213
    { NO_INPUT_TIMEOUT,                     "no-input-timeout" },
214
    { NUM_MAX_VERIFICATION_PHRASES,         "num-max-verification-phrases" },
215
    { NUM_MIN_CONSISTENT_PRONUNCIATIONS,    "num-min-consistent-pronunciations" },
216
    { NUM_MIN_VERIFICATION_PHRASES,         "num-min-verification-phrases" },
217
    { PERSONAL_GRAMMAR_URI,                 "personal-grammar-uri" },
218
    { PHRASE_ID,                            "phrase-id" },
219
    { PHRASE_NL,                            "phrase-nl" },
220
    { PROSODY_CONTOUR,                      "prosody-contour" },
221
    { PROSODY_DURATION,                     "prosody-duration" },
222
    { PROSODY_PITCH,                        "prosody-pitch" },
223
    { PROSODY_RANGE,                        "prosody-range" },
224
    { PROSODY_RATE,                         "prosody-rate" },
225
    { PROSODY_VOLUME,                       "prosody-volume" },
226
    { PROXY_SYNC_ID,                        "proxy-sync-id" },
227
    { RECOGNITION_MODE,                     "recognition-mode" },
228
    { RECOGNITION_TIMEOUT,                  "recognition-timeout" },
229
    { RECOGNIZER_CONTEXT_BLOCK,             "recognizer-context-block" },
230
    { RECORD_URI,                           "record-uri" },
231
    { REPOSITORY_URI,                       "repository-uri" },
232
    { SAVE_BEST_WAVEFORM,                   "save-best-waveform" },
233
    { SAVE_WAVEFORM,                        "save-waveform" },
234
    { SENSITIVITY_LEVEL,                    "sensitivity-level" },
235
    { SET_COOKIE,                           "set-cookie" },
236
    { SPEAK_LENGTH,                         "speak-length" },
237
    { SPEAK_RESTART,                        "speak-restart" },
238
    { SPEAKER_PROFILE,                      "speaker-profile" },
239
    { SPEECH_COMPLETE_TIMEOUT,              "speech-complete-timeout" },
240
    { SPEECH_INCOMPLETE_TIMEOUT,            "speech-incomplete-timeout" },
241
    { SPEECH_LANGUAGE,                      "speech-language" },
242
    { SPEECH_MARKER,                        "speech-marker" },
243
    { SPEED_VS_ACCURACY,                    "speed-vs-accuracy" },
244
    { START_INPUT_TIMERS,                   "start-input-timers" },
245
    { TRIM_LENGTH,                          "trim-length" },
246
    { VENDOR_SPECIFIC_PARAMETERS,           "vendor-specific-parameters" },
247
    { VER_BUFFER_UTTERANCE,                 "ver-buffer-utterance" },
248
    { VERIFICATION_MODE,                    "verification-mode" },
249
    { VOICE_AGE,                            "voice-age" },
250
    { VOICE_GENDER,                         "voice-gender" },
251
    { VOICE_NAME,                           "voice-name" },
252
    { VOICE_VARIANT,                        "voice-variant" },
253
    { VOICEPRINT_EXISTS,                    "voiceprint-exists" },
254
    { VOICEPRINT_IDENTIFIER,                "voiceprint-identifier" },
255
    { WAVEFORM_URI,                         "waveform-uri" },
256
    { WEIGHT,                               "weight" },
257
    { 0,    NULL }
258
};
259
260
261
/* Initialize the protocol and registered fields */
262
static int proto_mrcpv2;
263
static int hf_mrcpv2_Request_Line;
264
static int hf_mrcpv2_Response_Line;
265
static int hf_mrcpv2_Event_Line;
266
static int hf_mrcpv2_Unknown_Message;
267
static int hf_mrcpv2_Unknown_Header;
268
static int hf_mrcpv2_Data;
269
static int hf_mrcpv2_Method;
270
static int hf_mrcpv2_Event;
271
static int hf_mrcpv2_version;
272
static int hf_mrcpv2_message_length;
273
static int hf_mrcpv2_request_id;
274
static int hf_mrcpv2_status_code;
275
static int hf_mrcpv2_request_state;
276
static int hf_mrcpv2_Abort_Model;
277
static int hf_mrcpv2_Abort_Phrase_Enrollment;
278
static int hf_mrcpv2_Abort_Verification;
279
static int hf_mrcpv2_Accept;
280
static int hf_mrcpv2_Accept_Charset;
281
static int hf_mrcpv2_Active_Request_Id_List;
282
static int hf_mrcpv2_Adapt_Model;
283
static int hf_mrcpv2_Audio_Fetch_Hint;
284
static int hf_mrcpv2_Cache_Control;
285
static int hf_mrcpv2_Cancel_If_Queue;
286
static int hf_mrcpv2_Capture_On_Speech;
287
static int hf_mrcpv2_Channel_Identifier;
288
static int hf_mrcpv2_Clash_Threshold;
289
static int hf_mrcpv2_Clear_Dtmf_Buffer;
290
static int hf_mrcpv2_Completion_Cause;
291
static int hf_mrcpv2_Completion_Reason;
292
static int hf_mrcpv2_Confidence_Threshold;
293
static int hf_mrcpv2_Confusable_Phrases_URI;
294
static int hf_mrcpv2_Consistency_Threshold;
295
static int hf_mrcpv2_Content_Base;
296
static int hf_mrcpv2_Content_Encoding;
297
static int hf_mrcpv2_Content_ID;
298
static int hf_mrcpv2_Content_Length;
299
static int hf_mrcpv2_Content_Location;
300
static int hf_mrcpv2_Content_Type;
301
static int hf_mrcpv2_Dtmf_Buffer_Time;
302
static int hf_mrcpv2_Dtmf_Interdigit_Timeout;
303
static int hf_mrcpv2_Dtmf_Term_Char;
304
static int hf_mrcpv2_Dtmf_Term_Timeout;
305
static int hf_mrcpv2_Early_No_Match;
306
static int hf_mrcpv2_Enroll_Utterance;
307
static int hf_mrcpv2_Failed_URI;
308
static int hf_mrcpv2_Failed_URI_Cause;
309
static int hf_mrcpv2_Fetch_Hint;
310
static int hf_mrcpv2_Fetch_Timeout;
311
static int hf_mrcpv2_Final_Silence;
312
static int hf_mrcpv2_Hotword_Max_Duration;
313
static int hf_mrcpv2_Hotword_Min_Duration;
314
static int hf_mrcpv2_Input_Type;
315
static int hf_mrcpv2_Input_Waveform_URI;
316
static int hf_mrcpv2_Interpret_Text;
317
static int hf_mrcpv2_Jump_Size;
318
static int hf_mrcpv2_Kill_On_Barge_In;
319
static int hf_mrcpv2_Lexicon_Search_Order;
320
static int hf_mrcpv2_Load_Lexicon;
321
static int hf_mrcpv2_Logging_Tag;
322
static int hf_mrcpv2_Max_Time;
323
static int hf_mrcpv2_Media_Type;
324
static int hf_mrcpv2_Min_Verification_Score;
325
static int hf_mrcpv2_N_Best_List_Length;
326
static int hf_mrcpv2_New_Audio_Channel;
327
static int hf_mrcpv2_New_Phrase_ID;
328
static int hf_mrcpv2_No_Input_Timeout;
329
static int hf_mrcpv2_Num_Max_Verification_Phrases;
330
static int hf_mrcpv2_Num_Min_Consistent_Pronunciations;
331
static int hf_mrcpv2_Num_Min_Verification_Phrases;
332
static int hf_mrcpv2_Personal_Grammar_URI;
333
static int hf_mrcpv2_Phrase_ID;
334
static int hf_mrcpv2_Phrase_NL;
335
static int hf_mrcpv2_Prosody_Contour;
336
static int hf_mrcpv2_Prosody_Duration;
337
static int hf_mrcpv2_Prosody_Pitch;
338
static int hf_mrcpv2_Prosody_Range;
339
static int hf_mrcpv2_Prosody_Rate;
340
static int hf_mrcpv2_Prosody_Volume;
341
static int hf_mrcpv2_Proxy_Sync_Id;
342
static int hf_mrcpv2_Recognition_Mode;
343
static int hf_mrcpv2_Recognition_Timeout;
344
static int hf_mrcpv2_Recognizer_Context_Block;
345
static int hf_mrcpv2_Record_URI;
346
static int hf_mrcpv2_Repository_URI;
347
static int hf_mrcpv2_Save_Best_Waveform;
348
static int hf_mrcpv2_Save_Waveform;
349
static int hf_mrcpv2_Sensitivity_Level;
350
static int hf_mrcpv2_Set_Cookie;
351
static int hf_mrcpv2_Speak_Length;
352
static int hf_mrcpv2_Speak_Restart;
353
static int hf_mrcpv2_Speaker_Profile;
354
static int hf_mrcpv2_Speech_Complete_Timeout;
355
static int hf_mrcpv2_Speech_Incomplete_Timeout;
356
static int hf_mrcpv2_Speech_Language;
357
static int hf_mrcpv2_Speech_Marker;
358
static int hf_mrcpv2_Speed_Vs_Accuracy;
359
static int hf_mrcpv2_Start_Input_Timers;
360
static int hf_mrcpv2_Trim_Length;
361
static int hf_mrcpv2_Vendor_Specific_Parameters;
362
static int hf_mrcpv2_Ver_Buffer_Utterance;
363
static int hf_mrcpv2_Verification_Mode;
364
static int hf_mrcpv2_Voice_Age;
365
static int hf_mrcpv2_Voice_Gender;
366
static int hf_mrcpv2_Voice_Name;
367
static int hf_mrcpv2_Voice_Variant;
368
static int hf_mrcpv2_Voiceprint_Exists;
369
static int hf_mrcpv2_Voiceprint_Identifier;
370
static int hf_mrcpv2_Waveform_URI;
371
static int hf_mrcpv2_Weight;
372
373
static expert_field ei_mrcpv2_Content_Length_invalid;
374
375
/* Global MRCPv2 port pref */
376
15
#define TCP_DEFAULT_RANGE "6075, 30000-30200" /* Not IANA registered */
377
378
/* Initialize the subtree pointers */
379
static int ett_mrcpv2;
380
static int ett_Request_Line;
381
static int ett_Response_Line;
382
static int ett_Event_Line;
383
static int ett_Status_Code;
384
385
/* format status code description */
386
static const string_string status_code_vals[] = {
387
    { "200", "Success" },
388
    { "201", "Success with some optional header fields ignored" },
389
    { "401", "Client Failure: Method not allowed" },
390
    { "402", "Client Failure: Method not valid in this state" },
391
    { "403", "Client Failure: Unsupported header field" },
392
    { "404", "Client Failure: Illegal value for header field. This is the error for a syntax violation." },
393
    { "405", "Client Failure: Resource not allocated for this session or does not exist" },
394
    { "406", "Client Failure: Mandatory Header Field Missing" },
395
    { "407", "Client Failure: Method or Operation Failed (e.g., Grammar compilation failed in the recognizer. Detailed cause codes might be available through a resource specific header.)" },
396
    { "408", "Client Failure: Unrecognized or unsupported message entity" },
397
    { "409", "Client Failure: Unsupported Header Field Value. This is a value that is syntactically legal but exceeds the implementation's capabilities or expectations." },
398
    { "410", "Client Failure: Non-Monotonic or Out of order sequence number in request." },
399
    { "501", "Server Failure: Server Internal Error" },
400
    { "502", "Server Failure: Protocol Version not supported" },
401
    { "503", "Server Failure: Reserved for future assignment" },
402
    { "504", "Server Failure: Message too large" },
403
    { NULL, NULL }
404
};
405
406
/* Code to actually dissect the packets */
407
static int
408
dissect_mrcpv2_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
409
0
{
410
    /* Set up structures needed to add the protocol subtree and manage it */
411
0
    proto_item *ti;
412
0
    proto_tree *mrcpv2_tree;
413
0
    unsigned next_offset, linelen;
414
0
    unsigned tvb_len;
415
0
    uint32_t pdu_size;
416
0
    unsigned offset;
417
0
    unsigned value_offset;
418
0
    unsigned str_len;
419
0
    char *header_name;
420
0
    char *header_value;
421
0
    LINE_TYPE line_type = UNKNOWN_LINE;
422
0
    HEADER_TYPE header_type;
423
0
    unsigned colon_offset;
424
0
    uint32_t content_length;
425
0
    proto_item *line_item = NULL;
426
0
    proto_item *request_line_item = NULL;
427
0
    proto_item *response_line_item = NULL;
428
0
    proto_item *event_line_item = NULL;
429
0
    proto_item *status_code_item = NULL;
430
0
    proto_item *pi = NULL;
431
432
0
    unsigned sp_start;
433
0
    unsigned sp_end;
434
0
    const char *field1;
435
0
    const char *field2;
436
0
    const char *field3;
437
0
    const char *field4;
438
0
    const char *field5 = NULL;
439
440
    /* Make entries in Protocol column and Info column on summary display */
441
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "MRCPv2");
442
443
0
    offset = 0;
444
0
    tvb_len = tvb_reported_length(tvb);
445
446
0
    ti = proto_tree_add_item(tree, proto_mrcpv2, tvb, 0, -1, ENC_UTF_8);
447
0
    mrcpv2_tree = proto_item_add_subtree(ti, ett_mrcpv2);
448
449
    /* get first line */
450
0
    tvb_find_line_end_remaining(tvb, offset, &linelen , &next_offset);
451
452
    /*  find out MRCP message type:
453
454
        request-line    = mrcp-version SP message-length SP method-name SP request-id CRLF
455
        response-line    = mrcp-version SP message-length SP request-id  SP status-code SP request-state CRLF
456
        event-line    = mrcp-version SP message-length SP event-name  SP request-id  SP request-state CRLF
457
    */
458
    /* version */
459
0
    sp_end = tvb_find_uint8_length(tvb, 0, linelen, ' ', &sp_end);
460
0
    if ((!tvb_find_uint8_length(tvb, 0, linelen, ' ', &sp_end)) || (sp_end > tvb_len) || (sp_end > linelen)) {
461
0
        return -1;
462
0
    }
463
0
    field1 = (char*)tvb_get_string_enc(pinfo->pool, tvb, 0, sp_end, ENC_ASCII);
464
0
    sp_start = sp_end + 1;
465
466
    /* length */
467
0
    if ((!tvb_find_uint8_length(tvb, sp_start, linelen - sp_start, ' ', &sp_end)) || (sp_end > tvb_len) || (sp_end > linelen))
468
0
        return -1;
469
0
    field2 = (char*)tvb_get_string_enc(pinfo->pool, tvb, sp_start, sp_end - sp_start, ENC_ASCII);
470
0
    sp_start = sp_end + 1;
471
472
    /* method, request ID or event */
473
0
    if ((!tvb_find_uint8_length(tvb, sp_start, linelen - sp_start, ' ', &sp_end)) || (sp_end > tvb_len) || (sp_end > linelen))
474
0
        return -1;
475
0
    field3 = (char*)tvb_get_string_enc(pinfo->pool, tvb, sp_start, sp_end - sp_start, ENC_ASCII);
476
0
    sp_start = sp_end + 1;
477
478
    /* request ID or status code */
479
0
    if (!tvb_find_uint8_length(tvb, sp_start, linelen - sp_start, ' ', &sp_end))
480
0
    {
481
0
        field4 = (char*)tvb_get_string_enc(pinfo->pool, tvb, sp_start, linelen - sp_start, ENC_ASCII);
482
0
        line_type = REQUEST_LINE; /* only request line has 4 parameters */
483
0
    }
484
0
    else
485
0
    {
486
0
        if ((sp_end > tvb_len) || (sp_end > linelen))
487
0
            return -1;
488
0
        field4 = (char*)tvb_get_string_enc(pinfo->pool, tvb, sp_start, sp_end - sp_start, ENC_ASCII);
489
490
0
        if (g_ascii_isdigit(field3[0])) /* request ID is number, so it has to be response */
491
0
            line_type = RESPONSE_LINE;
492
0
        else
493
0
            line_type = EVENT_LINE;
494
495
0
        sp_start = sp_end + 1;
496
0
        sp_end = linelen;
497
0
        if ((sp_end > tvb_len) || (sp_end > linelen))
498
0
            return -1;
499
0
        field5 = (char*)tvb_get_string_enc(pinfo->pool, tvb, sp_start, sp_end - sp_start, ENC_ASCII);
500
0
    }
501
502
    /* check pdu size */
503
0
    if (!ws_strtou32(field2, NULL, &pdu_size) || pdu_size > (unsigned)tvb_len)
504
0
        return -1;
505
506
    /* process MRCP header line */
507
0
    switch(line_type){
508
0
    case REQUEST_LINE:
509
0
    {
510
0
        col_set_str(pinfo->cinfo, COL_INFO, "Request: ");
511
0
        line_item = proto_tree_add_item(mrcpv2_tree, hf_mrcpv2_Request_Line, tvb, offset, linelen, ENC_UTF_8);
512
0
        request_line_item = proto_item_add_subtree(line_item, ett_Request_Line);
513
        /* version */
514
0
        str_len = (int)strlen(field1);
515
0
        proto_tree_add_item(request_line_item, hf_mrcpv2_version, tvb, offset, str_len, ENC_UTF_8);
516
0
        offset += str_len + 1; /* add SP */
517
        /* message length */
518
0
        str_len = (int)strlen(field2);
519
0
        proto_tree_add_item(request_line_item, hf_mrcpv2_message_length, tvb, offset, str_len, ENC_UTF_8);
520
0
        offset += str_len + 1; /* add SP */
521
        /* method name */
522
0
        col_append_str(pinfo->cinfo, COL_INFO, field3);
523
0
        str_len = (int)strlen(field3);
524
0
        proto_tree_add_item(request_line_item, hf_mrcpv2_Method, tvb, offset, str_len, ENC_UTF_8);
525
0
        offset += str_len + 1; /* add SP */
526
        /* request ID */
527
0
        str_len = (int)strlen(field4);
528
0
        proto_tree_add_item(request_line_item, hf_mrcpv2_request_id, tvb, offset, str_len, ENC_UTF_8);
529
        /*offset += str_len + 2;*/ /* add CRLF */
530
0
    }
531
0
    break;
532
0
    case RESPONSE_LINE:
533
0
    {
534
0
        col_set_str(pinfo->cinfo, COL_INFO, "Response: ");
535
0
        line_item = proto_tree_add_item(mrcpv2_tree, hf_mrcpv2_Response_Line, tvb, offset, linelen, ENC_UTF_8);
536
0
        response_line_item = proto_item_add_subtree(line_item, ett_Response_Line);
537
        /* version */
538
0
        str_len = (int)strlen(field1);
539
0
        proto_tree_add_item(response_line_item, hf_mrcpv2_version, tvb, offset, str_len, ENC_UTF_8);
540
0
        offset += str_len + 1; /* add SP */
541
        /* message length */
542
0
        str_len = (int)strlen(field2);
543
0
        proto_tree_add_item(response_line_item, hf_mrcpv2_message_length, tvb, offset, str_len, ENC_UTF_8);
544
0
        offset += str_len + 1; /* add SP */
545
        /* request ID */
546
0
        str_len = (int)strlen(field3);
547
0
        proto_tree_add_item(response_line_item, hf_mrcpv2_request_id, tvb, offset, str_len, ENC_UTF_8);
548
0
        offset += str_len + 1; /* add SP */
549
        /* status code */
550
0
        str_len = (int)strlen(field4);
551
0
        status_code_item = proto_tree_add_item(response_line_item, hf_mrcpv2_status_code, tvb, offset,
552
0
            str_len, ENC_UTF_8);
553
0
        proto_item_append_text(status_code_item, " %s", str_to_str_wmem(pinfo->pool, field4, status_code_vals, "Unknown Status Code"));
554
0
        offset += str_len + 1; /* add SP */
555
        /* request state */
556
0
        col_append_fstr(pinfo->cinfo, COL_INFO, "(%s) %s", field4, field5);
557
0
        str_len = (int)strlen(field5);
558
0
        proto_tree_add_item(response_line_item, hf_mrcpv2_request_state, tvb, offset, str_len, ENC_UTF_8);
559
        /*offset += str_len + 2;*/ /* add CRLF */
560
0
    }
561
0
    break;
562
0
    case EVENT_LINE:
563
0
    {
564
0
        col_set_str(pinfo->cinfo, COL_INFO, "Event: ");
565
0
        line_item = proto_tree_add_item(mrcpv2_tree, hf_mrcpv2_Event_Line, tvb, offset, linelen, ENC_UTF_8);
566
0
        event_line_item = proto_item_add_subtree(line_item, ett_Event_Line);
567
        /* version */
568
0
        str_len = (int)strlen(field1);
569
0
        proto_tree_add_item(event_line_item, hf_mrcpv2_version, tvb, offset, str_len, ENC_UTF_8);
570
0
        offset += str_len + 1; /* add SP */
571
        /* message length */
572
0
        str_len = (int)strlen(field2);
573
0
        proto_tree_add_item(event_line_item, hf_mrcpv2_message_length, tvb, offset, str_len, ENC_UTF_8);
574
0
        offset += str_len + 1; /* add SP */
575
        /* event name */
576
0
        col_append_str(pinfo->cinfo, COL_INFO, field3);
577
0
        str_len = (int)strlen(field3);
578
0
        proto_tree_add_item(event_line_item, hf_mrcpv2_Event, tvb, offset, str_len, ENC_UTF_8);
579
0
        offset += str_len + 1; /* add SP */
580
        /* request ID */
581
0
        str_len = (int)strlen(field4);
582
0
        proto_tree_add_item(event_line_item, hf_mrcpv2_request_id, tvb, offset, str_len, ENC_UTF_8);
583
0
        offset += str_len + 1; /* add SP */
584
        /* request state */
585
0
        str_len = (int)strlen(field5);
586
0
        proto_tree_add_item(event_line_item, hf_mrcpv2_request_state, tvb, offset, str_len, ENC_UTF_8);
587
        /*offset += str_len + 2;*/ /* add CRLF */
588
0
    }
589
0
    break;
590
0
    default:
591
0
    {
592
        /* mark whole packet as unknown and return */
593
0
        col_set_str(pinfo->cinfo, COL_INFO, "UNKNOWN message");
594
0
        proto_tree_add_item(mrcpv2_tree, hf_mrcpv2_Unknown_Message, tvb, offset, tvb_len, ENC_UTF_8);
595
0
        return tvb_len;
596
0
    }
597
0
    }
598
599
0
    if (tree) {
600
        /* process the rest of the header lines here */
601
0
        content_length = 0;
602
0
        while (tvb_offset_exists(tvb, next_offset))
603
0
        {
604
            /* get next line */
605
0
            offset = next_offset;
606
0
            tvb_find_line_end_remaining(tvb, offset, &linelen , &next_offset);
607
608
            /* blank line separates msg header and msg body */
609
0
            if (linelen == 0)
610
0
            {
611
0
                if (content_length > 0)
612
0
                { /* content length > 0 and CRLF detected, this has to be msg body */
613
0
                    offset += 2; /* skip separating CRLF */
614
0
                    proto_tree_add_item(mrcpv2_tree, hf_mrcpv2_Data, tvb, offset, tvb_len - offset, ENC_ASCII);
615
0
                    next_offset = tvb_len; /* we are done */
616
0
                }
617
0
                continue;
618
0
            }
619
620
            /* get header type and its value */
621
0
            if (!tvb_find_uint8_length(tvb, offset, linelen, ':', &colon_offset))
622
0
            { /* header type should end with ':' */
623
0
                proto_tree_add_item(mrcpv2_tree, hf_mrcpv2_Unknown_Header, tvb, offset, linelen, ENC_UTF_8);
624
0
                continue;
625
0
            }
626
0
            header_name = (char*)tvb_get_string_enc(pinfo->pool, tvb, offset, colon_offset - offset, ENC_ASCII);
627
0
            ascii_strdown_inplace(header_name);
628
0
            value_offset = tvb_skip_wsp(tvb, colon_offset + 1, offset + linelen - (colon_offset + 1));
629
0
            header_value = (char*)tvb_get_string_enc(pinfo->pool, tvb, value_offset, offset + linelen - value_offset, ENC_ASCII);
630
631
            /* find out header type */
632
0
            header_type = (HEADER_TYPE)str_to_val(header_name, header_type_vals, UNKNOWN);
633
634
            /* add header type and value into the tree */
635
0
            switch (header_type)
636
0
            {
637
0
                case ABORT_MODEL:
638
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Abort_Model, tvb, offset, linelen, header_value);
639
0
                    break;
640
0
                case ABORT_PHRASE_ENROLLMENT:
641
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Abort_Phrase_Enrollment, tvb, offset, linelen, header_value);
642
0
                    break;
643
0
                case ABORT_VERIFICATION:
644
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Abort_Verification, tvb, offset, linelen, header_value);
645
0
                    break;
646
0
                case ACCEPT:
647
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Accept, tvb, offset, linelen, header_value);
648
0
                    break;
649
0
                case ACCEPT_CHARSET:
650
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Accept_Charset, tvb, offset, linelen, header_value);
651
0
                    break;
652
0
                case ACTIVE_REQUEST_ID_LIST:
653
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Active_Request_Id_List, tvb, offset, linelen, header_value);
654
0
                    break;
655
0
                case ADAPT_MODEL:
656
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Adapt_Model, tvb, offset, linelen, header_value);
657
0
                    break;
658
0
                case AUDIO_FETCH_HINT:
659
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Audio_Fetch_Hint, tvb, offset, linelen, header_value);
660
0
                    break;
661
0
                case CACHE_CONTROL:
662
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Cache_Control, tvb, offset, linelen, header_value);
663
0
                    break;
664
0
                case CANCEL_IF_QUEUE:
665
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Cancel_If_Queue, tvb, offset, linelen, header_value);
666
0
                    break;
667
0
                case CAPTURE_ON_SPEECH:
668
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Capture_On_Speech, tvb, offset, linelen, header_value);
669
0
                    break;
670
0
                case CHANNEL_IDENTIFIER:
671
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Channel_Identifier, tvb, offset, linelen, header_value);
672
0
                    break;
673
0
                case CLASH_THRESHOLD:
674
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Clash_Threshold, tvb, offset, linelen, header_value);
675
0
                    break;
676
0
                case CLEAR_DTMF_BUFFER:
677
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Clear_Dtmf_Buffer, tvb, offset, linelen, header_value);
678
0
                    break;
679
0
                case COMPLETION_CAUSE:
680
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Completion_Cause, tvb, offset, linelen, header_value);
681
0
                    break;
682
0
                case COMPLETION_REASON:
683
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Completion_Reason, tvb, offset, linelen, header_value);
684
0
                    break;
685
0
                case CONFIDENCE_THRESHOLD:
686
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Confidence_Threshold, tvb, offset, linelen, header_value);
687
0
                    break;
688
0
                case CONFUSABLE_PHRASES_URI:
689
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Confusable_Phrases_URI, tvb, offset, linelen, header_value);
690
0
                    break;
691
0
                case CONSISTENCY_THRESHOLD:
692
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Consistency_Threshold, tvb, offset, linelen, header_value);
693
0
                    break;
694
0
                case CONTENT_BASE:
695
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Content_Base, tvb, offset, linelen, header_value);
696
0
                    break;
697
0
                case CONTENT_ENCODING:
698
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Content_Encoding, tvb, offset, linelen, header_value);
699
0
                    break;
700
0
                case CONTENT_ID:
701
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Content_ID, tvb, offset, linelen, header_value);
702
0
                    break;
703
0
                case CONTENT_LENGTH:
704
0
                    pi = proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Content_Length, tvb, offset, linelen, header_value);
705
                    /* if content length is > 0, then there are some data after the headers */
706
0
                    if (!ws_strtou32(header_value, NULL, &content_length)) {
707
0
                        content_length = 0;
708
0
                        expert_add_info(pinfo, pi, &ei_mrcpv2_Content_Length_invalid);
709
0
                    }
710
0
                    break;
711
0
                case CONTENT_LOCATION:
712
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Content_Location, tvb, offset, linelen, header_value);
713
0
                    break;
714
0
                case CONTENT_TYPE:
715
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Content_Type, tvb, offset, linelen, header_value);
716
0
                    break;
717
0
                case DTMF_BUFFER_TIME:
718
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Dtmf_Buffer_Time, tvb, offset, linelen, header_value);
719
0
                    break;
720
0
                case DTMF_INTERDIGIT_TIMEOUT:
721
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Dtmf_Interdigit_Timeout, tvb, offset, linelen, header_value);
722
0
                    break;
723
0
                case DTMF_TERM_CHAR:
724
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Dtmf_Term_Char, tvb, offset, linelen, header_value);
725
0
                    break;
726
0
                case DTMF_TERM_TIMEOUT:
727
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Dtmf_Term_Timeout, tvb, offset, linelen, header_value);
728
0
                    break;
729
0
                case EARLY_NO_MATCH:
730
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Early_No_Match, tvb, offset, linelen, header_value);
731
0
                    break;
732
0
                case ENROLL_UTTERANCE:
733
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Enroll_Utterance, tvb, offset, linelen, header_value);
734
0
                    break;
735
0
                case FAILED_URI:
736
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Failed_URI, tvb, offset, linelen, header_value);
737
0
                    break;
738
0
                case FAILED_URI_CAUSE:
739
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Failed_URI_Cause, tvb, offset, linelen, header_value);
740
0
                    break;
741
0
                case FETCH_HINT:
742
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Fetch_Hint, tvb, offset, linelen, header_value);
743
0
                    break;
744
0
                case FETCH_TIMEOUT:
745
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Fetch_Timeout, tvb, offset, linelen, header_value);
746
0
                    break;
747
0
                case FINAL_SILENCE:
748
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Final_Silence, tvb, offset, linelen, header_value);
749
0
                    break;
750
0
                case HOTWORD_MAX_DURATION:
751
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Hotword_Max_Duration, tvb, offset, linelen, header_value);
752
0
                    break;
753
0
                case HOTWORD_MIN_DURATION:
754
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Hotword_Min_Duration, tvb, offset, linelen, header_value);
755
0
                    break;
756
0
                case INPUT_TYPE:
757
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Input_Type, tvb, offset, linelen, header_value);
758
0
                    break;
759
0
                case INPUT_WAVEFORM_URI:
760
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Input_Waveform_URI, tvb, offset, linelen, header_value);
761
0
                    break;
762
0
                case INTERPRET_TEXT:
763
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Interpret_Text, tvb, offset, linelen, header_value);
764
0
                    break;
765
0
                case JUMP_SIZE:
766
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Jump_Size, tvb, offset, linelen, header_value);
767
0
                    break;
768
0
                case KILL_ON_BARGE_IN:
769
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Kill_On_Barge_In, tvb, offset, linelen, header_value);
770
0
                    break;
771
0
                case LEXICON_SEARCH_ORDER:
772
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Lexicon_Search_Order, tvb, offset, linelen, header_value);
773
0
                    break;
774
0
                case LOAD_LEXICON:
775
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Load_Lexicon, tvb, offset, linelen, header_value);
776
0
                    break;
777
0
                case LOGGING_TAG:
778
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Logging_Tag, tvb, offset, linelen, header_value);
779
0
                    break;
780
0
                case MAX_TIME:
781
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Max_Time, tvb, offset, linelen, header_value);
782
0
                    break;
783
0
                case MEDIA_TYPE:
784
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Media_Type, tvb, offset, linelen, header_value);
785
0
                    break;
786
0
                case MIN_VERIFICATION_SCORE:
787
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Min_Verification_Score, tvb, offset, linelen, header_value);
788
0
                    break;
789
0
                case N_BEST_LIST_LENGTH:
790
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_N_Best_List_Length, tvb, offset, linelen, header_value);
791
0
                    break;
792
0
                case NEW_AUDIO_CHANNEL:
793
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_New_Audio_Channel, tvb, offset, linelen, header_value);
794
0
                    break;
795
0
                case NEW_PHRASE_ID:
796
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_New_Phrase_ID, tvb, offset, linelen, header_value);
797
0
                    break;
798
0
                case NO_INPUT_TIMEOUT:
799
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_No_Input_Timeout, tvb, offset, linelen, header_value);
800
0
                    break;
801
0
                case NUM_MAX_VERIFICATION_PHRASES:
802
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Num_Max_Verification_Phrases, tvb, offset, linelen, header_value);
803
0
                    break;
804
0
                case NUM_MIN_CONSISTENT_PRONUNCIATIONS:
805
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Num_Min_Consistent_Pronunciations, tvb, offset, linelen, header_value);
806
0
                    break;
807
0
                case NUM_MIN_VERIFICATION_PHRASES:
808
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Num_Min_Verification_Phrases, tvb, offset, linelen, header_value);
809
0
                    break;
810
0
                case PERSONAL_GRAMMAR_URI:
811
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Personal_Grammar_URI, tvb, offset, linelen, header_value);
812
0
                    break;
813
0
                case PHRASE_ID:
814
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Phrase_ID, tvb, offset, linelen, header_value);
815
0
                    break;
816
0
                case PHRASE_NL:
817
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Phrase_NL, tvb, offset, linelen, header_value);
818
0
                    break;
819
0
                case PROSODY_CONTOUR:
820
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Prosody_Contour, tvb, offset, linelen, header_value);
821
0
                    break;
822
0
                case PROSODY_DURATION:
823
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Prosody_Duration, tvb, offset, linelen, header_value);
824
0
                    break;
825
0
                case PROSODY_PITCH:
826
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Prosody_Pitch, tvb, offset, linelen, header_value);
827
0
                    break;
828
0
                case PROSODY_RANGE:
829
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Prosody_Range, tvb, offset, linelen, header_value);
830
0
                    break;
831
0
                case PROSODY_RATE:
832
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Prosody_Rate, tvb, offset, linelen, header_value);
833
0
                    break;
834
0
                case PROSODY_VOLUME:
835
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Prosody_Volume, tvb, offset, linelen, header_value);
836
0
                    break;
837
0
                case PROXY_SYNC_ID:
838
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Proxy_Sync_Id, tvb, offset, linelen, header_value);
839
0
                    break;
840
0
                case RECOGNITION_MODE:
841
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Recognition_Mode, tvb, offset, linelen, header_value);
842
0
                    break;
843
0
                case RECOGNITION_TIMEOUT:
844
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Recognition_Timeout, tvb, offset, linelen, header_value);
845
0
                    break;
846
0
                case RECOGNIZER_CONTEXT_BLOCK:
847
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Recognizer_Context_Block, tvb, offset, linelen, header_value);
848
0
                    break;
849
0
                case RECORD_URI:
850
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Record_URI, tvb, offset, linelen, header_value);
851
0
                    break;
852
0
                case REPOSITORY_URI:
853
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Repository_URI, tvb, offset, linelen, header_value);
854
0
                    break;
855
0
                case SAVE_BEST_WAVEFORM:
856
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Save_Best_Waveform, tvb, offset, linelen, header_value);
857
0
                    break;
858
0
                case SAVE_WAVEFORM:
859
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Save_Waveform, tvb, offset, linelen, header_value);
860
0
                    break;
861
0
                case SENSITIVITY_LEVEL:
862
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Sensitivity_Level, tvb, offset, linelen, header_value);
863
0
                    break;
864
0
                case SET_COOKIE:
865
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Set_Cookie, tvb, offset, linelen, header_value);
866
0
                    break;
867
0
                case SPEAK_LENGTH:
868
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Speak_Length, tvb, offset, linelen, header_value);
869
0
                    break;
870
0
                case SPEAK_RESTART:
871
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Speak_Restart, tvb, offset, linelen, header_value);
872
0
                    break;
873
0
                case SPEAKER_PROFILE:
874
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Speaker_Profile, tvb, offset, linelen, header_value);
875
0
                    break;
876
0
                case SPEECH_COMPLETE_TIMEOUT:
877
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Speech_Complete_Timeout, tvb, offset, linelen, header_value);
878
0
                    break;
879
0
                case SPEECH_INCOMPLETE_TIMEOUT:
880
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Speech_Incomplete_Timeout, tvb, offset, linelen, header_value);
881
0
                    break;
882
0
                case SPEECH_LANGUAGE:
883
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Speech_Language, tvb, offset, linelen, header_value);
884
0
                    break;
885
0
                case SPEECH_MARKER:
886
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Speech_Marker, tvb, offset, linelen, header_value);
887
0
                    break;
888
0
                case SPEED_VS_ACCURACY:
889
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Speed_Vs_Accuracy, tvb, offset, linelen, header_value);
890
0
                    break;
891
0
                case START_INPUT_TIMERS:
892
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Start_Input_Timers, tvb, offset, linelen, header_value);
893
0
                    break;
894
0
                case TRIM_LENGTH:
895
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Trim_Length, tvb, offset, linelen, header_value);
896
0
                    break;
897
0
                case VENDOR_SPECIFIC_PARAMETERS:
898
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Vendor_Specific_Parameters, tvb, offset, linelen, header_value);
899
0
                    break;
900
0
                case VER_BUFFER_UTTERANCE:
901
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Ver_Buffer_Utterance, tvb, offset, linelen, header_value);
902
0
                    break;
903
0
                case VERIFICATION_MODE:
904
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Verification_Mode, tvb, offset, linelen, header_value);
905
0
                    break;
906
0
                case VOICE_AGE:
907
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Voice_Age, tvb, offset, linelen, header_value);
908
0
                    break;
909
0
                case VOICE_GENDER:
910
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Voice_Gender, tvb, offset, linelen, header_value);
911
0
                    break;
912
0
                case VOICE_NAME:
913
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Voice_Name, tvb, offset, linelen, header_value);
914
0
                    break;
915
0
                case VOICE_VARIANT:
916
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Voice_Variant, tvb, offset, linelen, header_value);
917
0
                    break;
918
0
                case VOICEPRINT_EXISTS:
919
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Voiceprint_Exists, tvb, offset, linelen, header_value);
920
0
                    break;
921
0
                case VOICEPRINT_IDENTIFIER:
922
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Voiceprint_Identifier, tvb, offset, linelen, header_value);
923
0
                    break;
924
0
                case WAVEFORM_URI:
925
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Waveform_URI, tvb, offset, linelen, header_value);
926
0
                    break;
927
0
                case WEIGHT:
928
0
                    proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Weight, tvb, offset, linelen, header_value);
929
0
                    break;
930
0
                default:
931
0
                    proto_tree_add_item(mrcpv2_tree, hf_mrcpv2_Unknown_Header, tvb, offset, linelen, ENC_UTF_8);
932
0
                    break;
933
0
            }
934
0
        }
935
0
    }
936
937
    /* Return the amount of data this dissector was able to dissect */
938
0
    return tvb_captured_length(tvb);
939
0
}
940
941
/* get the length of the MRCP message */
942
static unsigned
943
get_mrcpv2_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
944
0
{
945
0
    unsigned len_start;
946
0
    unsigned len_end;
947
0
    const char *msg_len;
948
0
    uint32_t num_msg_len = 0;
949
950
    /* first string is version */
951
0
    if (!tvb_find_uint8_length(tvb, offset, MRCPV2_MIN_PDU_LEN, ' ', &len_start))
952
0
        return 0;
953
0
    len_start += 1; /* skip whitespace */
954
955
    /* second string is message length */
956
0
    if (!tvb_find_uint8_length(tvb, len_start, MRCPV2_MIN_PDU_LEN - len_start, ' ', &len_end))
957
0
        msg_len = (char*)tvb_get_string_enc(pinfo->pool, tvb, len_start, MRCPV2_MIN_PDU_LEN - len_start, ENC_ASCII);
958
0
    else
959
0
        msg_len = (char*)tvb_get_string_enc(pinfo->pool, tvb, len_start, len_end - len_start, ENC_ASCII);
960
961
0
    ws_strtou32(msg_len, NULL, &num_msg_len);
962
0
    return num_msg_len;
963
0
}
964
965
static int
966
dissect_mrcpv2_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
967
0
{
968
0
    return dissect_mrcpv2_common(tvb, pinfo, tree);
969
0
}
970
971
static int
972
dissect_mrcpv2_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
973
55
{
974
55
    unsigned len;
975
55
    unsigned value_size;
976
55
    const char *version;
977
55
    const char *major;
978
55
    const char *minor;
979
55
    unsigned slash_offset;
980
55
    unsigned dot_offset;
981
55
    unsigned sp_offset;
982
55
    uint32_t value;
983
984
55
    len = tvb_captured_length(tvb);
985
55
    if (len < MRCPV2_MIN_LENGTH) /* too short, can't conclude if it's mrcp */
986
6
        return 0;
987
988
    /* we are looking for MRCP string */
989
49
    slash_offset = tvb_find_uint8_length(tvb, 0, MRCPV2_MIN_LENGTH, '/', &slash_offset);
990
49
    if (slash_offset != 4)
991
49
        return 0;
992
0
    version = (char*)tvb_get_string_enc(pinfo->pool, tvb, 0, slash_offset, ENC_ASCII);
993
0
    if (strcmp(version, "MRCP") != 0)
994
0
        return 0;
995
996
    /* get first digit after the '/'; it should be 2 */
997
0
    if (!tvb_find_uint8_length(tvb, slash_offset + 1, MRCPV2_MIN_LENGTH - slash_offset - 1, '.', &dot_offset))
998
0
        return 0;
999
0
    value_size = dot_offset - slash_offset - 1;
1000
0
    if ((value_size != 1) && (value_size != 2))
1001
0
        return 0;
1002
0
    major = (char*)tvb_get_string_enc(pinfo->pool, tvb, slash_offset + 1, value_size, ENC_ASCII);
1003
0
    if (!ws_strtou32(major, NULL, &value) || value != 2)
1004
0
        return 0;
1005
1006
    /* get second digit, it should be 0 */
1007
0
    if (!tvb_find_uint8_length(tvb, dot_offset + 1, MRCPV2_MIN_LENGTH - dot_offset - 1, ' ', &sp_offset))
1008
0
    {
1009
0
        minor = (char*)tvb_get_string_enc(pinfo->pool, tvb, dot_offset + 1, MRCPV2_MIN_LENGTH - dot_offset - 1, ENC_ASCII);
1010
0
        len = MRCPV2_MIN_LENGTH;
1011
0
    }
1012
0
    else
1013
0
    {
1014
0
        minor = (char*)tvb_get_string_enc(pinfo->pool, tvb, dot_offset + 1, MRCPV2_MIN_LENGTH - sp_offset - 1, ENC_ASCII);
1015
0
        len = sp_offset;
1016
0
    }
1017
0
    if (!ws_strtou32(minor, NULL, &value) || value != 0)
1018
0
        return 0;
1019
1020
    /* if we are here, then we have MRCP v 2.0 protocol, so proceed with the dissection */
1021
0
    tcp_dissect_pdus(tvb, pinfo, tree, true, MRCPV2_MIN_PDU_LEN,
1022
0
                    get_mrcpv2_pdu_len,
1023
0
                    dissect_mrcpv2_tcp_pdu, data);
1024
0
    return len;
1025
0
}
1026
1027
void
1028
proto_register_mrcpv2(void)
1029
15
{
1030
15
    expert_module_t* expert_mrcpv2;
1031
1032
15
    static hf_register_info hf[] = {
1033
15
        { &hf_mrcpv2_Request_Line,
1034
15
            { "Request-Line", "mrcpv2.Request-Line",
1035
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
1036
15
        },
1037
15
        { &hf_mrcpv2_Response_Line,
1038
15
            { "Response-Line", "mrcpv2.Response-Line",
1039
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
1040
15
        },
1041
15
        { &hf_mrcpv2_Event_Line,
1042
15
            { "Event-Line", "mrcpv2.Event-Line",
1043
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
1044
15
        },
1045
15
        { &hf_mrcpv2_Unknown_Message,
1046
15
            { "Unknown Message", "mrcpv2.Unknown-Message",
1047
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
1048
15
        },
1049
15
        { &hf_mrcpv2_Unknown_Header,
1050
15
            { "Unknown Header", "mrcpv2.Unknown-Header",
1051
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
1052
15
        },
1053
15
        { &hf_mrcpv2_Data,
1054
15
            { "Message data", "mrcpv2.Data",
1055
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
1056
15
        },
1057
15
        { &hf_mrcpv2_Method,
1058
15
            { "Method", "mrcpv2.Method",
1059
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
1060
15
        },
1061
15
        { &hf_mrcpv2_Event,
1062
15
            { "Event", "mrcpv2.Event",
1063
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
1064
15
        },
1065
15
        { &hf_mrcpv2_version,
1066
15
            { "Version", "mrcpv2.Version",
1067
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
1068
15
        },
1069
15
        { &hf_mrcpv2_message_length,
1070
15
            { "Message Length", "mrcpv2.msg_len",
1071
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
1072
15
        },
1073
15
        { &hf_mrcpv2_request_id,
1074
15
            { "Request ID", "mrcpv2.reqID",
1075
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
1076
15
        },
1077
15
        { &hf_mrcpv2_status_code,
1078
15
            { "Status Code", "mrcpv2.status_code",
1079
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
1080
15
        },
1081
15
        { &hf_mrcpv2_request_state,
1082
15
            { "Request State", "mrcpv2.request_state",
1083
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
1084
15
        },
1085
15
        { &hf_mrcpv2_Abort_Model,
1086
15
            { "Abort-Model", "mrcpv2.Abort-Model",
1087
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1088
15
        },
1089
15
        { &hf_mrcpv2_Abort_Phrase_Enrollment,
1090
15
            { "Abort-Phrase-Enrollment", "mrcpv2.Abort-Phrase-Enrollment",
1091
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1092
15
        },
1093
15
        { &hf_mrcpv2_Abort_Verification,
1094
15
            { "Abort-Verification", "mrcpv2.Abort-Verification",
1095
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1096
15
        },
1097
15
        { &hf_mrcpv2_Accept,
1098
15
            { "Accept", "mrcpv2.Accept",
1099
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1100
15
        },
1101
15
        { &hf_mrcpv2_Accept_Charset,
1102
15
            { "Accept-Charset", "mrcpv2.Accept-Charset",
1103
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1104
15
        },
1105
15
        { &hf_mrcpv2_Active_Request_Id_List,
1106
15
            { "Active-Request-Id-List", "mrcpv2.Active-Request-Id-List",
1107
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1108
15
        },
1109
15
        { &hf_mrcpv2_Adapt_Model,
1110
15
            { "Adapt-Model", "mrcpv2.Adapt-Model",
1111
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1112
15
        },
1113
15
        { &hf_mrcpv2_Audio_Fetch_Hint,
1114
15
            { "Audio-Fetch-Hint", "mrcpv2.Audio-Fetch-Hint",
1115
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1116
15
        },
1117
15
        { &hf_mrcpv2_Cache_Control,
1118
15
            { "Cache-Control", "mrcpv2.Cache-Control",
1119
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1120
15
        },
1121
15
        { &hf_mrcpv2_Cancel_If_Queue,
1122
15
            { "Cancel-If-Queue", "mrcpv2.Cancel-If-Queue",
1123
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1124
15
        },
1125
15
        { &hf_mrcpv2_Capture_On_Speech,
1126
15
            { "Capture-On-Speech", "mrcpv2.Capture-On-Speech",
1127
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1128
15
        },
1129
15
        { &hf_mrcpv2_Channel_Identifier,
1130
15
            { "Channel-Identifier", "mrcpv2.Channel-Identifier",
1131
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1132
15
        },
1133
15
        { &hf_mrcpv2_Clash_Threshold,
1134
15
            { "Clash-Threshold", "mrcpv2.Clash-Threshold",
1135
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1136
15
        },
1137
15
        { &hf_mrcpv2_Clear_Dtmf_Buffer,
1138
15
            { "Clear-Dtmf-Buffer", "mrcpv2.Clear-Dtmf-Buffer",
1139
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1140
15
        },
1141
15
        { &hf_mrcpv2_Completion_Cause,
1142
15
            { "Completion-Cause", "mrcpv2.Completion-Cause",
1143
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1144
15
        },
1145
15
        { &hf_mrcpv2_Completion_Reason,
1146
15
            { "Completion-Reason", "mrcpv2.Completion-Reason",
1147
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1148
15
        },
1149
15
        { &hf_mrcpv2_Confidence_Threshold,
1150
15
            { "Confidence-Threshold", "mrcpv2.Confidence-Threshold",
1151
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1152
15
        },
1153
15
        { &hf_mrcpv2_Confusable_Phrases_URI,
1154
15
            { "Confusable-Phrases-URI", "mrcpv2.Confusable-Phrases-URI",
1155
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1156
15
        },
1157
15
        { &hf_mrcpv2_Consistency_Threshold,
1158
15
            { "Consistency-Threshold", "mrcpv2.Consistency-Threshold",
1159
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1160
15
        },
1161
15
        { &hf_mrcpv2_Content_Base,
1162
15
            { "Content-Base", "mrcpv2.Content-Base",
1163
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1164
15
        },
1165
15
        { &hf_mrcpv2_Content_Encoding,
1166
15
            { "Content-Encoding", "mrcpv2.Content-Encoding",
1167
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1168
15
        },
1169
15
        { &hf_mrcpv2_Content_ID,
1170
15
            { "Content-ID", "mrcpv2.Content-ID",
1171
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1172
15
        },
1173
15
        { &hf_mrcpv2_Content_Length,
1174
15
            { "Content-Length", "mrcpv2.Content-Length",
1175
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1176
15
        },
1177
15
        { &hf_mrcpv2_Content_Location,
1178
15
            { "Content-Location", "mrcpv2.Content-Location",
1179
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1180
15
        },
1181
15
        { &hf_mrcpv2_Content_Type,
1182
15
            { "Content-Type", "mrcpv2.Content-Type",
1183
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1184
15
        },
1185
15
        { &hf_mrcpv2_Dtmf_Buffer_Time,
1186
15
            { "Dtmf-Buffer-Time", "mrcpv2.Dtmf-Buffer-Time",
1187
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1188
15
        },
1189
15
        { &hf_mrcpv2_Dtmf_Interdigit_Timeout,
1190
15
            { "Dtmf-Interdigit-Timeout", "mrcpv2.Dtmf-Interdigit-Timeout",
1191
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1192
15
        },
1193
15
        { &hf_mrcpv2_Dtmf_Term_Char,
1194
15
            { "Dtmf-Term-Char", "mrcpv2.Dtmf-Term-Char",
1195
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1196
15
        },
1197
15
        { &hf_mrcpv2_Dtmf_Term_Timeout,
1198
15
            { "Dtmf-Term-Timeout", "mrcpv2.Dtmf-Term-Timeout",
1199
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1200
15
        },
1201
15
        { &hf_mrcpv2_Early_No_Match,
1202
15
            { "Early-No-Match", "mrcpv2.Early-No-Match",
1203
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1204
15
        },
1205
15
        { &hf_mrcpv2_Enroll_Utterance,
1206
15
            { "Enroll-Utterance", "mrcpv2.Enroll-Utterance",
1207
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1208
15
        },
1209
15
        { &hf_mrcpv2_Failed_URI,
1210
15
            { "Failed-URI", "mrcpv2.Failed-URI",
1211
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1212
15
        },
1213
15
        { &hf_mrcpv2_Failed_URI_Cause,
1214
15
            { "Failed-URI-Cause", "mrcpv2.Failed-URI-Cause",
1215
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1216
15
        },
1217
15
        { &hf_mrcpv2_Fetch_Hint,
1218
15
            { "Fetch-Hint", "mrcpv2.Fetch-Hint",
1219
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1220
15
        },
1221
15
        { &hf_mrcpv2_Fetch_Timeout,
1222
15
            { "Fetch-Timeout", "mrcpv2.Fetch-Timeout",
1223
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1224
15
        },
1225
15
        { &hf_mrcpv2_Final_Silence,
1226
15
            { "Final-Silence", "mrcpv2.Final-Silence",
1227
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1228
15
        },
1229
15
        { &hf_mrcpv2_Hotword_Max_Duration,
1230
15
            { "Hotword-Max-Duration", "mrcpv2.Hotword-Max-Duration",
1231
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1232
15
        },
1233
15
        { &hf_mrcpv2_Hotword_Min_Duration,
1234
15
            { "Hotword-Min-Duration", "mrcpv2.Hotword-Min-Duration",
1235
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1236
15
        },
1237
15
        { &hf_mrcpv2_Input_Type,
1238
15
            { "Input-Type", "mrcpv2.Input-Type",
1239
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1240
15
        },
1241
15
        { &hf_mrcpv2_Input_Waveform_URI,
1242
15
            { "Input-Waveform-URI", "mrcpv2.Input-Waveform-URI",
1243
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1244
15
        },
1245
15
        { &hf_mrcpv2_Interpret_Text,
1246
15
            { "Interpret-Text", "mrcpv2.Interpret-Text",
1247
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1248
15
        },
1249
15
        { &hf_mrcpv2_Jump_Size,
1250
15
            { "Jump-Size", "mrcpv2.Jump-Size",
1251
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1252
15
        },
1253
15
        { &hf_mrcpv2_Kill_On_Barge_In,
1254
15
            { "Kill-On-Barge-In", "mrcpv2.Kill-On-Barge-In",
1255
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1256
15
        },
1257
15
        { &hf_mrcpv2_Lexicon_Search_Order,
1258
15
            { "Lexicon-Search-Order", "mrcpv2.Lexicon-Search-Order",
1259
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1260
15
        },
1261
15
        { &hf_mrcpv2_Load_Lexicon,
1262
15
            { "Load-Lexicon", "mrcpv2.Load-Lexicon",
1263
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1264
15
        },
1265
15
        { &hf_mrcpv2_Logging_Tag,
1266
15
            { "Logging-Tag", "mrcpv2.Logging-Tag",
1267
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1268
15
        },
1269
15
        { &hf_mrcpv2_Max_Time,
1270
15
            { "Max-Time", "mrcpv2.Max-Time",
1271
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1272
15
        },
1273
15
        { &hf_mrcpv2_Media_Type,
1274
15
            { "Media-Type", "mrcpv2.Media-Type",
1275
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1276
15
        },
1277
15
        { &hf_mrcpv2_Min_Verification_Score,
1278
15
            { "Min-Verification-Score", "mrcpv2.Min-Verification-Score",
1279
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1280
15
        },
1281
15
        { &hf_mrcpv2_N_Best_List_Length,
1282
15
            { "N-Best-List-Length", "mrcpv2.N-Best-List-Length",
1283
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1284
15
        },
1285
15
        { &hf_mrcpv2_New_Audio_Channel,
1286
15
            { "New-Audio-Channel", "mrcpv2.New-Audio-Channel",
1287
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1288
15
        },
1289
15
        { &hf_mrcpv2_New_Phrase_ID,
1290
15
            { "New-Phrase-ID", "mrcpv2.New-Phrase-ID",
1291
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1292
15
        },
1293
15
        { &hf_mrcpv2_No_Input_Timeout,
1294
15
            { "No-Input-Timeout", "mrcpv2.No-Input-Timeout",
1295
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1296
15
        },
1297
15
        { &hf_mrcpv2_Num_Max_Verification_Phrases,
1298
15
            { "Num-Max-Verification-Phrases", "mrcpv2.Num-Max-Verification-Phrases",
1299
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1300
15
        },
1301
15
        { &hf_mrcpv2_Num_Min_Consistent_Pronunciations,
1302
15
            { "Num-Min-Consistent-Pronunciations", "mrcpv2.Num-Min-Consistent-Pronunciations",
1303
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1304
15
        },
1305
15
        { &hf_mrcpv2_Num_Min_Verification_Phrases,
1306
15
            { "Num-Min-Verification-Phrases", "mrcpv2.Num-Min-Verification-Phrases",
1307
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1308
15
        },
1309
15
        { &hf_mrcpv2_Personal_Grammar_URI,
1310
15
            { "Personal-Grammar-URI", "mrcpv2.Personal-Grammar-URI",
1311
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1312
15
        },
1313
15
        { &hf_mrcpv2_Phrase_ID,
1314
15
            { "Phrase-ID", "mrcpv2.Phrase-ID",
1315
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1316
15
        },
1317
15
        { &hf_mrcpv2_Phrase_NL,
1318
15
            { "Phrase-NL", "mrcpv2.Phrase-NL",
1319
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1320
15
        },
1321
15
        { &hf_mrcpv2_Prosody_Contour,
1322
15
            { "Prosody-Contour", "mrcpv2.Prosody-Contour",
1323
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1324
15
        },
1325
15
        { &hf_mrcpv2_Prosody_Duration,
1326
15
            { "Prosody-Duration", "mrcpv2.Prosody-Duration",
1327
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1328
15
        },
1329
15
        { &hf_mrcpv2_Prosody_Pitch,
1330
15
            { "Prosody-Pitch", "mrcpv2.Prosody-Pitch",
1331
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1332
15
        },
1333
15
        { &hf_mrcpv2_Prosody_Range,
1334
15
            { "Prosody-Range", "mrcpv2.Prosody-Range",
1335
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1336
15
        },
1337
15
        { &hf_mrcpv2_Prosody_Rate,
1338
15
            { "Prosody-Rate", "mrcpv2.Prosody-Rate",
1339
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1340
15
        },
1341
15
        { &hf_mrcpv2_Prosody_Volume,
1342
15
            { "Prosody-Volume", "mrcpv2.Prosody-Volume",
1343
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1344
15
        },
1345
15
        { &hf_mrcpv2_Proxy_Sync_Id,
1346
15
            { "Proxy-Sync-Id", "mrcpv2.Proxy-Sync-Id",
1347
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1348
15
        },
1349
15
        { &hf_mrcpv2_Recognition_Mode,
1350
15
            { "Recognition-Mode", "mrcpv2.Recognition-Mode",
1351
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1352
15
        },
1353
15
        { &hf_mrcpv2_Recognition_Timeout,
1354
15
            { "Recognition-Timeout", "mrcpv2.Recognition-Timeout",
1355
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1356
15
        },
1357
15
        { &hf_mrcpv2_Recognizer_Context_Block,
1358
15
            { "Recognizer-Context-Block", "mrcpv2.Recognizer-Context-Block",
1359
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1360
15
        },
1361
15
        { &hf_mrcpv2_Record_URI,
1362
15
            { "Record-URI", "mrcpv2.Record-URI",
1363
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1364
15
        },
1365
15
        { &hf_mrcpv2_Repository_URI,
1366
15
            { "Repository-URI", "mrcpv2.Repository-URI",
1367
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1368
15
        },
1369
15
        { &hf_mrcpv2_Save_Best_Waveform,
1370
15
            { "Save-Best-Waveform", "mrcpv2.Save-Best-Waveform",
1371
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1372
15
        },
1373
15
        { &hf_mrcpv2_Save_Waveform,
1374
15
            { "Save-Waveform", "mrcpv2.Save-Waveform",
1375
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1376
15
        },
1377
15
        { &hf_mrcpv2_Sensitivity_Level,
1378
15
            { "Sensitivity-Level", "mrcpv2.Sensitivity-Level",
1379
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1380
15
        },
1381
15
        { &hf_mrcpv2_Set_Cookie,
1382
15
            { "Set-Cookie", "mrcpv2.Set-Cookie",
1383
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1384
15
        },
1385
15
        { &hf_mrcpv2_Speak_Length,
1386
15
            { "Speak-Length", "mrcpv2.Speak-Length",
1387
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1388
15
        },
1389
15
        { &hf_mrcpv2_Speak_Restart,
1390
15
            { "Speak-Restart", "mrcpv2.Speak-Restart",
1391
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1392
15
        },
1393
15
        { &hf_mrcpv2_Speaker_Profile,
1394
15
            { "Speaker-Profile", "mrcpv2.Speaker-Profile",
1395
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1396
15
        },
1397
15
        { &hf_mrcpv2_Speech_Complete_Timeout,
1398
15
            { "Speech-Complete-Timeout", "mrcpv2.Speech-Complete-Timeout",
1399
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1400
15
        },
1401
15
        { &hf_mrcpv2_Speech_Incomplete_Timeout,
1402
15
            { "Speech-Incomplete-Timeout", "mrcpv2.Speech-Incomplete-Timeout",
1403
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1404
15
        },
1405
15
        { &hf_mrcpv2_Speech_Language,
1406
15
            { "Speech-Language", "mrcpv2.Speech-Language",
1407
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1408
15
        },
1409
15
        { &hf_mrcpv2_Speech_Marker,
1410
15
            { "Speech-Marker", "mrcpv2.Speech-Marker",
1411
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1412
15
        },
1413
15
        { &hf_mrcpv2_Speed_Vs_Accuracy,
1414
15
            { "Speed-Vs-Accuracy", "mrcpv2.Speed-Vs-Accuracy",
1415
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1416
15
        },
1417
15
        { &hf_mrcpv2_Start_Input_Timers,
1418
15
            { "Start-Input-Timers", "mrcpv2.Start-Input-Timers",
1419
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1420
15
        },
1421
15
        { &hf_mrcpv2_Trim_Length,
1422
15
            { "Trim-Length", "mrcpv2.Trim-Length",
1423
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1424
15
        },
1425
15
        { &hf_mrcpv2_Vendor_Specific_Parameters,
1426
15
            { "Vendor-Specific-Parameters", "mrcpv2.Vendor-Specific-Parameters",
1427
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1428
15
        },
1429
15
        { &hf_mrcpv2_Ver_Buffer_Utterance,
1430
15
            { "Ver-Buffer-Utterance", "mrcpv2.Ver-Buffer-Utterance",
1431
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1432
15
        },
1433
15
        { &hf_mrcpv2_Verification_Mode,
1434
15
            { "Verification-Mode", "mrcpv2.Verification-Mode",
1435
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1436
15
        },
1437
15
        { &hf_mrcpv2_Voice_Age,
1438
15
            { "Voice-Age", "mrcpv2.Voice-Age",
1439
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1440
15
        },
1441
15
        { &hf_mrcpv2_Voice_Gender,
1442
15
            { "Voice-Gender", "mrcpv2.Voice-Gender",
1443
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1444
15
        },
1445
15
        { &hf_mrcpv2_Voice_Name,
1446
15
            { "Voice-Name", "mrcpv2.Voice-Name",
1447
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1448
15
        },
1449
15
        { &hf_mrcpv2_Voice_Variant,
1450
15
            { "Voice-Variant", "mrcpv2.Voice-Variant",
1451
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1452
15
        },
1453
15
        { &hf_mrcpv2_Voiceprint_Exists,
1454
15
            { "Voiceprint-Exists", "mrcpv2.Voiceprint-Exists",
1455
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1456
15
        },
1457
15
        { &hf_mrcpv2_Voiceprint_Identifier,
1458
15
            { "Voiceprint-Identifier", "mrcpv2.Voiceprint-Identifier",
1459
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1460
15
        },
1461
15
        { &hf_mrcpv2_Waveform_URI,
1462
15
            { "Waveform-URI", "mrcpv2.Waveform-URI",
1463
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1464
15
        },
1465
15
        { &hf_mrcpv2_Weight,
1466
15
            { "Weight", "mrcpv2.Weight",
1467
15
            FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1468
15
        }
1469
15
    };
1470
1471
15
    static ei_register_info ei[] = {
1472
15
        { &ei_mrcpv2_Content_Length_invalid, { "mrcpv2.Content-Length.invalid", PI_MALFORMED, PI_ERROR,
1473
15
        "Content Length must be a string containing an integer", EXPFILL }}
1474
15
    };
1475
1476
15
    static int *ett[] = {
1477
15
        &ett_mrcpv2,
1478
15
        &ett_Request_Line,
1479
15
        &ett_Response_Line,
1480
15
        &ett_Event_Line,
1481
15
        &ett_Status_Code
1482
15
    };
1483
1484
15
    proto_mrcpv2 = proto_register_protocol("Media Resource Control Protocol Version 2 (MRCPv2)", "MRCPv2", "mrcpv2");
1485
1486
15
    proto_register_field_array(proto_mrcpv2, hf, array_length(hf));
1487
15
    proto_register_subtree_array(ett, array_length(ett));
1488
1489
15
    expert_mrcpv2 = expert_register_protocol(proto_mrcpv2);
1490
15
    expert_register_field_array(expert_mrcpv2, ei, array_length(ei));
1491
1492
15
    mrcpv2_handle = register_dissector("mrcpv2", dissect_mrcpv2_tcp, proto_mrcpv2);
1493
15
}
1494
1495
void
1496
proto_reg_handoff_mrcpv2(void)
1497
15
{
1498
15
    dissector_add_uint_range_with_preference ("tcp.port", TCP_DEFAULT_RANGE, mrcpv2_handle);
1499
15
}
1500
/*
1501
 * Editor modelines
1502
 *
1503
 * Local Variables:
1504
 * c-basic-offset: 4
1505
 * tab-width: 8
1506
 * indent-tabs-mode: nil
1507
 * End:
1508
 *
1509
 * ex: set shiftwidth=4 tabstop=8 expandtab:
1510
 * :indentSize=4:tabSize=8:noTabs=true:
1511
 */