epan/dissectors/pidl/ C99 drsuapi
[wireshark-sm.git] / epan / dissectors / packet-mrcpv2.c
blob67d842d4b2ac2693cd90f3ce8e7edbd314d95375
1 /* packet-mrcpv2.c
2 * Routines for Media Resource Control Protocol Version 2 (MRCPv2) dissection
3 * Copyright 2012, Zeljko Ancimer <zancimer[AT]gmail.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
12 * Based on RFC 6787
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")
23 #include "config.h"
25 /* Include only as needed */
26 #include <stdlib.h>
28 #include <epan/packet.h>
29 #include <epan/expert.h>
30 #include "packet-tcp.h"
32 #include <wsutil/str_util.h>
33 #include <wsutil/strtoi.h>
35 void proto_register_mrcpv2(void);
36 void proto_reg_handoff_mrcpv2(void);
38 static dissector_handle_t mrcpv2_handle;
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 */
46 /* min length to determine MRCPv2 version */
47 #define MRCPV2_MIN_LENGTH 10
48 /* min length to determine MRCPv2 PDU length */
49 #define MRCPV2_MIN_PDU_LEN 30
51 /* line type */
52 typedef enum {
53 REQUEST_LINE,
54 RESPONSE_LINE,
55 EVENT_LINE,
56 UNKNOWN_LINE
57 } LINE_TYPE;
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;
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 }
260 /* Initialize the protocol and registered fields */
261 static int proto_mrcpv2;
262 static int hf_mrcpv2_Request_Line;
263 static int hf_mrcpv2_Response_Line;
264 static int hf_mrcpv2_Event_Line;
265 static int hf_mrcpv2_Unknown_Message;
266 static int hf_mrcpv2_Unknown_Header;
267 static int hf_mrcpv2_Data;
268 static int hf_mrcpv2_Method;
269 static int hf_mrcpv2_Event;
270 static int hf_mrcpv2_version;
271 static int hf_mrcpv2_message_length;
272 static int hf_mrcpv2_request_id;
273 static int hf_mrcpv2_status_code;
274 static int hf_mrcpv2_request_state;
275 static int hf_mrcpv2_Abort_Model;
276 static int hf_mrcpv2_Abort_Phrase_Enrollment;
277 static int hf_mrcpv2_Abort_Verification;
278 static int hf_mrcpv2_Accept;
279 static int hf_mrcpv2_Accept_Charset;
280 static int hf_mrcpv2_Active_Request_Id_List;
281 static int hf_mrcpv2_Adapt_Model;
282 static int hf_mrcpv2_Audio_Fetch_Hint;
283 static int hf_mrcpv2_Cache_Control;
284 static int hf_mrcpv2_Cancel_If_Queue;
285 static int hf_mrcpv2_Capture_On_Speech;
286 static int hf_mrcpv2_Channel_Identifier;
287 static int hf_mrcpv2_Clash_Threshold;
288 static int hf_mrcpv2_Clear_Dtmf_Buffer;
289 static int hf_mrcpv2_Completion_Cause;
290 static int hf_mrcpv2_Completion_Reason;
291 static int hf_mrcpv2_Confidence_Threshold;
292 static int hf_mrcpv2_Confusable_Phrases_URI;
293 static int hf_mrcpv2_Consistency_Threshold;
294 static int hf_mrcpv2_Content_Base;
295 static int hf_mrcpv2_Content_Encoding;
296 static int hf_mrcpv2_Content_ID;
297 static int hf_mrcpv2_Content_Length;
298 static int hf_mrcpv2_Content_Location;
299 static int hf_mrcpv2_Content_Type;
300 static int hf_mrcpv2_Dtmf_Buffer_Time;
301 static int hf_mrcpv2_Dtmf_Interdigit_Timeout;
302 static int hf_mrcpv2_Dtmf_Term_Char;
303 static int hf_mrcpv2_Dtmf_Term_Timeout;
304 static int hf_mrcpv2_Early_No_Match;
305 static int hf_mrcpv2_Enroll_Utterance;
306 static int hf_mrcpv2_Failed_URI;
307 static int hf_mrcpv2_Failed_URI_Cause;
308 static int hf_mrcpv2_Fetch_Hint;
309 static int hf_mrcpv2_Fetch_Timeout;
310 static int hf_mrcpv2_Final_Silence;
311 static int hf_mrcpv2_Hotword_Max_Duration;
312 static int hf_mrcpv2_Hotword_Min_Duration;
313 static int hf_mrcpv2_Input_Type;
314 static int hf_mrcpv2_Input_Waveform_URI;
315 static int hf_mrcpv2_Interpret_Text;
316 static int hf_mrcpv2_Jump_Size;
317 static int hf_mrcpv2_Kill_On_Barge_In;
318 static int hf_mrcpv2_Lexicon_Search_Order;
319 static int hf_mrcpv2_Load_Lexicon;
320 static int hf_mrcpv2_Logging_Tag;
321 static int hf_mrcpv2_Max_Time;
322 static int hf_mrcpv2_Media_Type;
323 static int hf_mrcpv2_Min_Verification_Score;
324 static int hf_mrcpv2_N_Best_List_Length;
325 static int hf_mrcpv2_New_Audio_Channel;
326 static int hf_mrcpv2_New_Phrase_ID;
327 static int hf_mrcpv2_No_Input_Timeout;
328 static int hf_mrcpv2_Num_Max_Verification_Phrases;
329 static int hf_mrcpv2_Num_Min_Consistent_Pronunciations;
330 static int hf_mrcpv2_Num_Min_Verification_Phrases;
331 static int hf_mrcpv2_Personal_Grammar_URI;
332 static int hf_mrcpv2_Phrase_ID;
333 static int hf_mrcpv2_Phrase_NL;
334 static int hf_mrcpv2_Prosody_Contour;
335 static int hf_mrcpv2_Prosody_Duration;
336 static int hf_mrcpv2_Prosody_Pitch;
337 static int hf_mrcpv2_Prosody_Range;
338 static int hf_mrcpv2_Prosody_Rate;
339 static int hf_mrcpv2_Prosody_Volume;
340 static int hf_mrcpv2_Proxy_Sync_Id;
341 static int hf_mrcpv2_Recognition_Mode;
342 static int hf_mrcpv2_Recognition_Timeout;
343 static int hf_mrcpv2_Recognizer_Context_Block;
344 static int hf_mrcpv2_Record_URI;
345 static int hf_mrcpv2_Repository_URI;
346 static int hf_mrcpv2_Save_Best_Waveform;
347 static int hf_mrcpv2_Save_Waveform;
348 static int hf_mrcpv2_Sensitivity_Level;
349 static int hf_mrcpv2_Set_Cookie;
350 static int hf_mrcpv2_Speak_Length;
351 static int hf_mrcpv2_Speak_Restart;
352 static int hf_mrcpv2_Speaker_Profile;
353 static int hf_mrcpv2_Speech_Complete_Timeout;
354 static int hf_mrcpv2_Speech_Incomplete_Timeout;
355 static int hf_mrcpv2_Speech_Language;
356 static int hf_mrcpv2_Speech_Marker;
357 static int hf_mrcpv2_Speed_Vs_Accuracy;
358 static int hf_mrcpv2_Start_Input_Timers;
359 static int hf_mrcpv2_Trim_Length;
360 static int hf_mrcpv2_Vendor_Specific_Parameters;
361 static int hf_mrcpv2_Ver_Buffer_Utterance;
362 static int hf_mrcpv2_Verification_Mode;
363 static int hf_mrcpv2_Voice_Age;
364 static int hf_mrcpv2_Voice_Gender;
365 static int hf_mrcpv2_Voice_Name;
366 static int hf_mrcpv2_Voice_Variant;
367 static int hf_mrcpv2_Voiceprint_Exists;
368 static int hf_mrcpv2_Voiceprint_Identifier;
369 static int hf_mrcpv2_Waveform_URI;
370 static int hf_mrcpv2_Weight;
372 static expert_field ei_mrcpv2_Content_Length_invalid;
374 /* Global MRCPv2 port pref */
375 #define TCP_DEFAULT_RANGE "6075, 30000-30200" /* Not IANA registered */
377 /* Initialize the subtree pointers */
378 static int ett_mrcpv2;
379 static int ett_Request_Line;
380 static int ett_Response_Line;
381 static int ett_Event_Line;
382 static int ett_Status_Code;
384 /* format status code description */
385 static const string_string status_code_vals[] = {
386 { "200", "Success" },
387 { "201", "Success with some optional header fields ignored" },
388 { "401", "Client Failure: Method not allowed" },
389 { "402", "Client Failure: Method not valid in this state" },
390 { "403", "Client Failure: Unsupported header field" },
391 { "404", "Client Failure: Illegal value for header field. This is the error for a syntax violation." },
392 { "405", "Client Failure: Resource not allocated for this session or does not exist" },
393 { "406", "Client Failure: Mandatory Header Field Missing" },
394 { "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.)" },
395 { "408", "Client Failure: Unrecognized or unsupported message entity" },
396 { "409", "Client Failure: Unsupported Header Field Value. This is a value that is syntactically legal but exceeds the implementation's capabilities or expectations." },
397 { "410", "Client Failure: Non-Monotonic or Out of order sequence number in request." },
398 { "501", "Server Failure: Server Internal Error" },
399 { "502", "Server Failure: Protocol Version not supported" },
400 { "503", "Server Failure: Reserved for future assignment" },
401 { "504", "Server Failure: Message too large" },
402 { NULL, NULL }
405 /* Code to actually dissect the packets */
406 static int
407 dissect_mrcpv2_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
409 /* Set up structures needed to add the protocol subtree and manage it */
410 proto_item *ti;
411 proto_tree *mrcpv2_tree;
412 int next_offset, linelen;
413 int tvb_len;
414 int pdu_size;
415 int offset;
416 int value_offset;
417 int str_len;
418 char *header_name;
419 char *header_value;
420 LINE_TYPE line_type = UNKNOWN_LINE;
421 HEADER_TYPE header_type;
422 int colon_offset;
423 int content_length;
424 const value_string *p = NULL;
425 proto_item *line_item = NULL;
426 proto_item *request_line_item = NULL;
427 proto_item *response_line_item = NULL;
428 proto_item *event_line_item = NULL;
429 proto_item *status_code_item = NULL;
430 proto_item *pi = NULL;
432 int sp_start;
433 int sp_end;
434 uint8_t *field1;
435 uint8_t *field2;
436 uint8_t *field3;
437 uint8_t *field4;
438 uint8_t *field5 = NULL;
440 /* Make entries in Protocol column and Info column on summary display */
441 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MRCPv2");
443 offset = 0;
444 tvb_len = tvb_reported_length(tvb);
446 ti = proto_tree_add_item(tree, proto_mrcpv2, tvb, 0, -1, ENC_UTF_8);
447 mrcpv2_tree = proto_item_add_subtree(ti, ett_mrcpv2);
449 /* get first line */
450 linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, false);
452 /* find out MRCP message type:
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
458 /* version */
459 sp_end = tvb_find_uint8(tvb, 0, linelen, ' ');
460 if ((sp_end == -1) || (sp_end > tvb_len) || (sp_end > linelen))
461 return -1;
462 field1 = tvb_get_string_enc(pinfo->pool, tvb, 0, sp_end, ENC_ASCII);
463 sp_start = sp_end + 1;
465 /* length */
466 sp_end = tvb_find_uint8(tvb, sp_start, linelen - sp_start, ' ');
467 if ((sp_end == -1) || (sp_end > tvb_len) || (sp_end > linelen))
468 return -1;
469 field2 = tvb_get_string_enc(pinfo->pool, tvb, sp_start, sp_end - sp_start, ENC_ASCII);
470 sp_start = sp_end + 1;
472 /* method, request ID or event */
473 sp_end = tvb_find_uint8(tvb, sp_start, linelen - sp_start, ' ');
474 if ((sp_end == -1) || (sp_end > tvb_len) || (sp_end > linelen))
475 return -1;
476 field3 = tvb_get_string_enc(pinfo->pool, tvb, sp_start, sp_end - sp_start, ENC_ASCII);
477 sp_start = sp_end + 1;
479 /* request ID or status code */
480 sp_end = tvb_find_uint8(tvb, sp_start, linelen - sp_start, ' ');
481 if (sp_end == -1)
483 field4 = tvb_get_string_enc(pinfo->pool, tvb, sp_start, linelen - sp_start, ENC_ASCII);
484 line_type = REQUEST_LINE; /* only request line has 4 parameters */
486 else
488 if ((sp_end > tvb_len) || (sp_end > linelen))
489 return -1;
490 field4 = tvb_get_string_enc(pinfo->pool, tvb, sp_start, sp_end - sp_start, ENC_ASCII);
492 if (g_ascii_isdigit(field3[0])) /* request ID is number, so it has to be response */
493 line_type = RESPONSE_LINE;
494 else
495 line_type = EVENT_LINE;
497 sp_start = sp_end + 1;
498 sp_end = linelen;
499 if ((sp_end > tvb_len) || (sp_end > linelen))
500 return -1;
501 field5 = tvb_get_string_enc(pinfo->pool, tvb, sp_start, sp_end - sp_start, ENC_ASCII);
504 /* check pdu size */
505 if (!ws_strtou32(field2, NULL, &pdu_size) || pdu_size > tvb_len)
506 return -1;
508 /* process MRCP header line */
509 switch(line_type){
510 case REQUEST_LINE:
512 col_set_str(pinfo->cinfo, COL_INFO, "Request: ");
513 line_item = proto_tree_add_item(mrcpv2_tree, hf_mrcpv2_Request_Line, tvb, offset, linelen, ENC_UTF_8);
514 request_line_item = proto_item_add_subtree(line_item, ett_Request_Line);
515 /* version */
516 str_len = (int)strlen(field1);
517 proto_tree_add_item(request_line_item, hf_mrcpv2_version, tvb, offset, str_len, ENC_UTF_8);
518 offset += str_len + 1; /* add SP */
519 /* message length */
520 str_len = (int)strlen(field2);
521 proto_tree_add_item(request_line_item, hf_mrcpv2_message_length, tvb, offset, str_len, ENC_UTF_8);
522 offset += str_len + 1; /* add SP */
523 /* method name */
524 col_append_str(pinfo->cinfo, COL_INFO, field3);
525 str_len = (int)strlen(field3);
526 proto_tree_add_item(request_line_item, hf_mrcpv2_Method, tvb, offset, str_len, ENC_UTF_8);
527 offset += str_len + 1; /* add SP */
528 /* request ID */
529 str_len = (int)strlen(field4);
530 proto_tree_add_item(request_line_item, hf_mrcpv2_request_id, tvb, offset, str_len, ENC_UTF_8);
531 /*offset += str_len + 2;*/ /* add CRLF */
533 break;
534 case RESPONSE_LINE:
536 col_set_str(pinfo->cinfo, COL_INFO, "Response: ");
537 line_item = proto_tree_add_item(mrcpv2_tree, hf_mrcpv2_Response_Line, tvb, offset, linelen, ENC_UTF_8);
538 response_line_item = proto_item_add_subtree(line_item, ett_Response_Line);
539 /* version */
540 str_len = (int)strlen(field1);
541 proto_tree_add_item(response_line_item, hf_mrcpv2_version, tvb, offset, str_len, ENC_UTF_8);
542 offset += str_len + 1; /* add SP */
543 /* message length */
544 str_len = (int)strlen(field2);
545 proto_tree_add_item(response_line_item, hf_mrcpv2_message_length, tvb, offset, str_len, ENC_UTF_8);
546 offset += str_len + 1; /* add SP */
547 /* request ID */
548 str_len = (int)strlen(field3);
549 proto_tree_add_item(response_line_item, hf_mrcpv2_request_id, tvb, offset, str_len, ENC_UTF_8);
550 offset += str_len + 1; /* add SP */
551 /* status code */
552 str_len = (int)strlen(field4);
553 status_code_item = proto_tree_add_item(response_line_item, hf_mrcpv2_status_code, tvb, offset,
554 str_len, ENC_UTF_8);
555 proto_item_append_text(status_code_item, " %s", str_to_str(field4, status_code_vals, "Unknown Status Code"));
556 offset += str_len + 1; /* add SP */
557 /* request state */
558 col_append_fstr(pinfo->cinfo, COL_INFO, "(%s) %s", field4, field5);
559 str_len = (int)strlen(field5);
560 proto_tree_add_item(response_line_item, hf_mrcpv2_request_state, tvb, offset, str_len, ENC_UTF_8);
561 /*offset += str_len + 2;*/ /* add CRLF */
563 break;
564 case EVENT_LINE:
566 col_set_str(pinfo->cinfo, COL_INFO, "Event: ");
567 line_item = proto_tree_add_item(mrcpv2_tree, hf_mrcpv2_Event_Line, tvb, offset, linelen, ENC_UTF_8);
568 event_line_item = proto_item_add_subtree(line_item, ett_Event_Line);
569 /* version */
570 str_len = (int)strlen(field1);
571 proto_tree_add_item(event_line_item, hf_mrcpv2_version, tvb, offset, str_len, ENC_UTF_8);
572 offset += str_len + 1; /* add SP */
573 /* message length */
574 str_len = (int)strlen(field2);
575 proto_tree_add_item(event_line_item, hf_mrcpv2_message_length, tvb, offset, str_len, ENC_UTF_8);
576 offset += str_len + 1; /* add SP */
577 /* event name */
578 col_append_str(pinfo->cinfo, COL_INFO, field3);
579 str_len = (int)strlen(field3);
580 proto_tree_add_item(event_line_item, hf_mrcpv2_Event, tvb, offset, str_len, ENC_UTF_8);
581 offset += str_len + 1; /* add SP */
582 /* request ID */
583 str_len = (int)strlen(field4);
584 proto_tree_add_item(event_line_item, hf_mrcpv2_request_id, tvb, offset, str_len, ENC_UTF_8);
585 offset += str_len + 1; /* add SP */
586 /* request state */
587 str_len = (int)strlen(field5);
588 proto_tree_add_item(event_line_item, hf_mrcpv2_request_state, tvb, offset, str_len, ENC_UTF_8);
589 /*offset += str_len + 2;*/ /* add CRLF */
591 break;
592 default:
594 /* mark whole packet as unknown and return */
595 col_set_str(pinfo->cinfo, COL_INFO, "UNKNOWN message");
596 proto_tree_add_item(mrcpv2_tree, hf_mrcpv2_Unknown_Message, tvb, offset, tvb_len, ENC_UTF_8);
597 return tvb_len;
601 if (tree) {
602 /* process the rest of the header lines here */
603 content_length = 0;
604 while (tvb_offset_exists(tvb, next_offset))
606 /* get next line */
607 offset = next_offset;
608 linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, false);
610 /* blank line separates msg header and msg body */
611 if (linelen == 0)
613 if (content_length > 0)
614 { /* content length > 0 and CRLF detected, this has to be msg body */
615 offset += 2; /* skip separating CRLF */
616 proto_tree_add_item(mrcpv2_tree, hf_mrcpv2_Data, tvb, offset, tvb_len - offset, ENC_ASCII);
617 next_offset = tvb_len; /* we are done */
619 continue;
622 /* get header type and its value */
623 colon_offset = tvb_find_uint8(tvb, offset, linelen, ':');
624 if (colon_offset == -1)
625 { /* header type should end with ':' */
626 proto_tree_add_item(mrcpv2_tree, hf_mrcpv2_Unknown_Header, tvb, offset, linelen, ENC_UTF_8);
627 continue;
629 header_name = tvb_get_string_enc(pinfo->pool, tvb, offset, colon_offset - offset, ENC_ASCII);
630 ascii_strdown_inplace(header_name);
631 value_offset = tvb_skip_wsp(tvb, colon_offset + 1, offset + linelen - (colon_offset + 1));
632 header_value = tvb_get_string_enc(pinfo->pool, tvb, value_offset, offset + linelen - value_offset, ENC_ASCII);
634 /* find out header type */
635 header_type = UNKNOWN;
636 for (p = header_type_vals; p->strptr != NULL; ++p)
638 if (strncmp(p->strptr, header_name, strlen(p->strptr)) == 0)
640 header_type = (HEADER_TYPE)p->value;
641 break;
645 /* add header type and value into the tree */
646 switch (header_type)
648 case ABORT_MODEL:
649 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Abort_Model, tvb, offset, linelen, header_value);
650 break;
651 case ABORT_PHRASE_ENROLLMENT:
652 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Abort_Phrase_Enrollment, tvb, offset, linelen, header_value);
653 break;
654 case ABORT_VERIFICATION:
655 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Abort_Verification, tvb, offset, linelen, header_value);
656 break;
657 case ACCEPT:
658 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Accept, tvb, offset, linelen, header_value);
659 break;
660 case ACCEPT_CHARSET:
661 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Accept_Charset, tvb, offset, linelen, header_value);
662 break;
663 case ACTIVE_REQUEST_ID_LIST:
664 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Active_Request_Id_List, tvb, offset, linelen, header_value);
665 break;
666 case ADAPT_MODEL:
667 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Adapt_Model, tvb, offset, linelen, header_value);
668 break;
669 case AUDIO_FETCH_HINT:
670 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Audio_Fetch_Hint, tvb, offset, linelen, header_value);
671 break;
672 case CACHE_CONTROL:
673 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Cache_Control, tvb, offset, linelen, header_value);
674 break;
675 case CANCEL_IF_QUEUE:
676 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Cancel_If_Queue, tvb, offset, linelen, header_value);
677 break;
678 case CAPTURE_ON_SPEECH:
679 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Capture_On_Speech, tvb, offset, linelen, header_value);
680 break;
681 case CHANNEL_IDENTIFIER:
682 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Channel_Identifier, tvb, offset, linelen, header_value);
683 break;
684 case CLASH_THRESHOLD:
685 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Clash_Threshold, tvb, offset, linelen, header_value);
686 break;
687 case CLEAR_DTMF_BUFFER:
688 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Clear_Dtmf_Buffer, tvb, offset, linelen, header_value);
689 break;
690 case COMPLETION_CAUSE:
691 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Completion_Cause, tvb, offset, linelen, header_value);
692 break;
693 case COMPLETION_REASON:
694 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Completion_Reason, tvb, offset, linelen, header_value);
695 break;
696 case CONFIDENCE_THRESHOLD:
697 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Confidence_Threshold, tvb, offset, linelen, header_value);
698 break;
699 case CONFUSABLE_PHRASES_URI:
700 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Confusable_Phrases_URI, tvb, offset, linelen, header_value);
701 break;
702 case CONSISTENCY_THRESHOLD:
703 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Consistency_Threshold, tvb, offset, linelen, header_value);
704 break;
705 case CONTENT_BASE:
706 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Content_Base, tvb, offset, linelen, header_value);
707 break;
708 case CONTENT_ENCODING:
709 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Content_Encoding, tvb, offset, linelen, header_value);
710 break;
711 case CONTENT_ID:
712 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Content_ID, tvb, offset, linelen, header_value);
713 break;
714 case CONTENT_LENGTH:
715 pi = proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Content_Length, tvb, offset, linelen, header_value);
716 /* if content length is > 0, then there are some data after the headers */
717 if (!ws_strtou32(header_value, NULL, &content_length)) {
718 content_length = 0;
719 expert_add_info(pinfo, pi, &ei_mrcpv2_Content_Length_invalid);
721 break;
722 case CONTENT_LOCATION:
723 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Content_Location, tvb, offset, linelen, header_value);
724 break;
725 case CONTENT_TYPE:
726 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Content_Type, tvb, offset, linelen, header_value);
727 break;
728 case DTMF_BUFFER_TIME:
729 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Dtmf_Buffer_Time, tvb, offset, linelen, header_value);
730 break;
731 case DTMF_INTERDIGIT_TIMEOUT:
732 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Dtmf_Interdigit_Timeout, tvb, offset, linelen, header_value);
733 break;
734 case DTMF_TERM_CHAR:
735 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Dtmf_Term_Char, tvb, offset, linelen, header_value);
736 break;
737 case DTMF_TERM_TIMEOUT:
738 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Dtmf_Term_Timeout, tvb, offset, linelen, header_value);
739 break;
740 case EARLY_NO_MATCH:
741 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Early_No_Match, tvb, offset, linelen, header_value);
742 break;
743 case ENROLL_UTTERANCE:
744 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Enroll_Utterance, tvb, offset, linelen, header_value);
745 break;
746 case FAILED_URI:
747 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Failed_URI, tvb, offset, linelen, header_value);
748 break;
749 case FAILED_URI_CAUSE:
750 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Failed_URI_Cause, tvb, offset, linelen, header_value);
751 break;
752 case FETCH_HINT:
753 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Fetch_Hint, tvb, offset, linelen, header_value);
754 break;
755 case FETCH_TIMEOUT:
756 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Fetch_Timeout, tvb, offset, linelen, header_value);
757 break;
758 case FINAL_SILENCE:
759 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Final_Silence, tvb, offset, linelen, header_value);
760 break;
761 case HOTWORD_MAX_DURATION:
762 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Hotword_Max_Duration, tvb, offset, linelen, header_value);
763 break;
764 case HOTWORD_MIN_DURATION:
765 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Hotword_Min_Duration, tvb, offset, linelen, header_value);
766 break;
767 case INPUT_TYPE:
768 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Input_Type, tvb, offset, linelen, header_value);
769 break;
770 case INPUT_WAVEFORM_URI:
771 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Input_Waveform_URI, tvb, offset, linelen, header_value);
772 break;
773 case INTERPRET_TEXT:
774 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Interpret_Text, tvb, offset, linelen, header_value);
775 break;
776 case JUMP_SIZE:
777 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Jump_Size, tvb, offset, linelen, header_value);
778 break;
779 case KILL_ON_BARGE_IN:
780 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Kill_On_Barge_In, tvb, offset, linelen, header_value);
781 break;
782 case LEXICON_SEARCH_ORDER:
783 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Lexicon_Search_Order, tvb, offset, linelen, header_value);
784 break;
785 case LOAD_LEXICON:
786 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Load_Lexicon, tvb, offset, linelen, header_value);
787 break;
788 case LOGGING_TAG:
789 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Logging_Tag, tvb, offset, linelen, header_value);
790 break;
791 case MAX_TIME:
792 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Max_Time, tvb, offset, linelen, header_value);
793 break;
794 case MEDIA_TYPE:
795 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Media_Type, tvb, offset, linelen, header_value);
796 break;
797 case MIN_VERIFICATION_SCORE:
798 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Min_Verification_Score, tvb, offset, linelen, header_value);
799 break;
800 case N_BEST_LIST_LENGTH:
801 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_N_Best_List_Length, tvb, offset, linelen, header_value);
802 break;
803 case NEW_AUDIO_CHANNEL:
804 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_New_Audio_Channel, tvb, offset, linelen, header_value);
805 break;
806 case NEW_PHRASE_ID:
807 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_New_Phrase_ID, tvb, offset, linelen, header_value);
808 break;
809 case NO_INPUT_TIMEOUT:
810 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_No_Input_Timeout, tvb, offset, linelen, header_value);
811 break;
812 case NUM_MAX_VERIFICATION_PHRASES:
813 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Num_Max_Verification_Phrases, tvb, offset, linelen, header_value);
814 break;
815 case NUM_MIN_CONSISTENT_PRONUNCIATIONS:
816 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Num_Min_Consistent_Pronunciations, tvb, offset, linelen, header_value);
817 break;
818 case NUM_MIN_VERIFICATION_PHRASES:
819 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Num_Min_Verification_Phrases, tvb, offset, linelen, header_value);
820 break;
821 case PERSONAL_GRAMMAR_URI:
822 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Personal_Grammar_URI, tvb, offset, linelen, header_value);
823 break;
824 case PHRASE_ID:
825 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Phrase_ID, tvb, offset, linelen, header_value);
826 break;
827 case PHRASE_NL:
828 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Phrase_NL, tvb, offset, linelen, header_value);
829 break;
830 case PROSODY_CONTOUR:
831 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Prosody_Contour, tvb, offset, linelen, header_value);
832 break;
833 case PROSODY_DURATION:
834 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Prosody_Duration, tvb, offset, linelen, header_value);
835 break;
836 case PROSODY_PITCH:
837 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Prosody_Pitch, tvb, offset, linelen, header_value);
838 break;
839 case PROSODY_RANGE:
840 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Prosody_Range, tvb, offset, linelen, header_value);
841 break;
842 case PROSODY_RATE:
843 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Prosody_Rate, tvb, offset, linelen, header_value);
844 break;
845 case PROSODY_VOLUME:
846 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Prosody_Volume, tvb, offset, linelen, header_value);
847 break;
848 case PROXY_SYNC_ID:
849 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Proxy_Sync_Id, tvb, offset, linelen, header_value);
850 break;
851 case RECOGNITION_MODE:
852 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Recognition_Mode, tvb, offset, linelen, header_value);
853 break;
854 case RECOGNITION_TIMEOUT:
855 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Recognition_Timeout, tvb, offset, linelen, header_value);
856 break;
857 case RECOGNIZER_CONTEXT_BLOCK:
858 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Recognizer_Context_Block, tvb, offset, linelen, header_value);
859 break;
860 case RECORD_URI:
861 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Record_URI, tvb, offset, linelen, header_value);
862 break;
863 case REPOSITORY_URI:
864 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Repository_URI, tvb, offset, linelen, header_value);
865 break;
866 case SAVE_BEST_WAVEFORM:
867 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Save_Best_Waveform, tvb, offset, linelen, header_value);
868 break;
869 case SAVE_WAVEFORM:
870 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Save_Waveform, tvb, offset, linelen, header_value);
871 break;
872 case SENSITIVITY_LEVEL:
873 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Sensitivity_Level, tvb, offset, linelen, header_value);
874 break;
875 case SET_COOKIE:
876 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Set_Cookie, tvb, offset, linelen, header_value);
877 break;
878 case SPEAK_LENGTH:
879 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Speak_Length, tvb, offset, linelen, header_value);
880 break;
881 case SPEAK_RESTART:
882 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Speak_Restart, tvb, offset, linelen, header_value);
883 break;
884 case SPEAKER_PROFILE:
885 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Speaker_Profile, tvb, offset, linelen, header_value);
886 break;
887 case SPEECH_COMPLETE_TIMEOUT:
888 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Speech_Complete_Timeout, tvb, offset, linelen, header_value);
889 break;
890 case SPEECH_INCOMPLETE_TIMEOUT:
891 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Speech_Incomplete_Timeout, tvb, offset, linelen, header_value);
892 break;
893 case SPEECH_LANGUAGE:
894 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Speech_Language, tvb, offset, linelen, header_value);
895 break;
896 case SPEECH_MARKER:
897 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Speech_Marker, tvb, offset, linelen, header_value);
898 break;
899 case SPEED_VS_ACCURACY:
900 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Speed_Vs_Accuracy, tvb, offset, linelen, header_value);
901 break;
902 case START_INPUT_TIMERS:
903 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Start_Input_Timers, tvb, offset, linelen, header_value);
904 break;
905 case TRIM_LENGTH:
906 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Trim_Length, tvb, offset, linelen, header_value);
907 break;
908 case VENDOR_SPECIFIC_PARAMETERS:
909 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Vendor_Specific_Parameters, tvb, offset, linelen, header_value);
910 break;
911 case VER_BUFFER_UTTERANCE:
912 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Ver_Buffer_Utterance, tvb, offset, linelen, header_value);
913 break;
914 case VERIFICATION_MODE:
915 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Verification_Mode, tvb, offset, linelen, header_value);
916 break;
917 case VOICE_AGE:
918 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Voice_Age, tvb, offset, linelen, header_value);
919 break;
920 case VOICE_GENDER:
921 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Voice_Gender, tvb, offset, linelen, header_value);
922 break;
923 case VOICE_NAME:
924 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Voice_Name, tvb, offset, linelen, header_value);
925 break;
926 case VOICE_VARIANT:
927 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Voice_Variant, tvb, offset, linelen, header_value);
928 break;
929 case VOICEPRINT_EXISTS:
930 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Voiceprint_Exists, tvb, offset, linelen, header_value);
931 break;
932 case VOICEPRINT_IDENTIFIER:
933 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Voiceprint_Identifier, tvb, offset, linelen, header_value);
934 break;
935 case WAVEFORM_URI:
936 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Waveform_URI, tvb, offset, linelen, header_value);
937 break;
938 case WEIGHT:
939 proto_tree_add_string(mrcpv2_tree, hf_mrcpv2_Weight, tvb, offset, linelen, header_value);
940 break;
941 default:
942 proto_tree_add_item(mrcpv2_tree, hf_mrcpv2_Unknown_Header, tvb, offset, linelen, ENC_UTF_8);
943 break;
948 /* Return the amount of data this dissector was able to dissect */
949 return tvb_captured_length(tvb);
952 /* get the length of the MRCP message */
953 static unsigned
954 get_mrcpv2_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
956 int len_start;
957 int len_end;
958 uint8_t *msg_len;
959 unsigned num_msg_len = 0;
961 /* first string is version */
962 len_start = tvb_find_uint8(tvb, offset, MRCPV2_MIN_PDU_LEN, ' ');
963 if (len_start == -1)
964 return 0;
965 len_start += 1; /* skip whitespace */
967 /* second string is message length */
968 len_end = tvb_find_uint8(tvb, len_start, MRCPV2_MIN_PDU_LEN - len_start, ' ');
969 if (len_end == -1)
970 msg_len = tvb_get_string_enc(pinfo->pool, tvb, len_start, MRCPV2_MIN_PDU_LEN - len_start, ENC_ASCII);
971 else
972 msg_len = tvb_get_string_enc(pinfo->pool, tvb, len_start, len_end - len_start, ENC_ASCII);
974 ws_strtou32(msg_len, NULL, &num_msg_len);
975 return num_msg_len;
978 static int
979 dissect_mrcpv2_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
981 return dissect_mrcpv2_common(tvb, pinfo, tree);
984 static int
985 dissect_mrcpv2_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
987 int len;
988 int value_size;
989 uint8_t *version;
990 uint8_t *major;
991 uint8_t *minor;
992 int slash_offset;
993 int dot_offset;
994 int sp_offset;
995 int value;
997 len = tvb_captured_length(tvb);
998 if (len < MRCPV2_MIN_LENGTH) /* too short, can't conclude if it's mrcp */
999 return 0;
1001 /* we are looking for MRCP string */
1002 slash_offset = tvb_find_uint8(tvb, 0, MRCPV2_MIN_LENGTH, '/');
1003 if (slash_offset != 4)
1004 return 0;
1005 version = tvb_get_string_enc(pinfo->pool, tvb, 0, slash_offset, ENC_ASCII);
1006 if (strcmp(version, "MRCP") != 0)
1007 return 0;
1009 /* get first digit after the '/'; it should be 2 */
1010 dot_offset = tvb_find_uint8(tvb, slash_offset + 1, MRCPV2_MIN_LENGTH - slash_offset - 1, '.');
1011 if (dot_offset == -1)
1012 return 0;
1013 value_size = dot_offset - slash_offset - 1;
1014 if ((value_size != 1) && (value_size != 2))
1015 return 0;
1016 major = tvb_get_string_enc(pinfo->pool, tvb, slash_offset + 1, value_size, ENC_ASCII);
1017 if (!ws_strtou32(major, NULL, &value) || value != 2)
1018 return 0;
1020 /* get second digit, it should be 0 */
1021 sp_offset = tvb_find_uint8(tvb, dot_offset + 1, MRCPV2_MIN_LENGTH - dot_offset - 1, ' ');
1022 if (sp_offset == -1)
1024 minor = tvb_get_string_enc(pinfo->pool, tvb, dot_offset + 1, MRCPV2_MIN_LENGTH - dot_offset - 1, ENC_ASCII);
1025 len = MRCPV2_MIN_LENGTH;
1027 else
1029 minor = tvb_get_string_enc(pinfo->pool, tvb, dot_offset + 1, MRCPV2_MIN_LENGTH - sp_offset - 1, ENC_ASCII);
1030 len = sp_offset;
1032 if (!ws_strtou32(minor, NULL, &value) || value != 0)
1033 return 0;
1035 /* if we are here, then we have MRCP v 2.0 protocol, so proceed with the dissection */
1036 tcp_dissect_pdus(tvb, pinfo, tree, true, MRCPV2_MIN_PDU_LEN,
1037 get_mrcpv2_pdu_len,
1038 dissect_mrcpv2_tcp_pdu, data);
1039 return len;
1042 void
1043 proto_register_mrcpv2(void)
1045 expert_module_t* expert_mrcpv2;
1047 static hf_register_info hf[] = {
1048 { &hf_mrcpv2_Request_Line,
1049 { "Request-Line", "mrcpv2.Request-Line",
1050 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
1052 { &hf_mrcpv2_Response_Line,
1053 { "Response-Line", "mrcpv2.Response-Line",
1054 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
1056 { &hf_mrcpv2_Event_Line,
1057 { "Event-Line", "mrcpv2.Event-Line",
1058 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
1060 { &hf_mrcpv2_Unknown_Message,
1061 { "Unknown Message", "mrcpv2.Unknown-Message",
1062 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
1064 { &hf_mrcpv2_Unknown_Header,
1065 { "Unknown Header", "mrcpv2.Unknown-Header",
1066 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
1068 { &hf_mrcpv2_Data,
1069 { "Message data", "mrcpv2.Data",
1070 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
1072 { &hf_mrcpv2_Method,
1073 { "Method", "mrcpv2.Method",
1074 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
1076 { &hf_mrcpv2_Event,
1077 { "Event", "mrcpv2.Event",
1078 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
1080 { &hf_mrcpv2_version,
1081 { "Version", "mrcpv2.Version",
1082 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
1084 { &hf_mrcpv2_message_length,
1085 { "Message Length", "mrcpv2.msg_len",
1086 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
1088 { &hf_mrcpv2_request_id,
1089 { "Request ID", "mrcpv2.reqID",
1090 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
1092 { &hf_mrcpv2_status_code,
1093 { "Status Code", "mrcpv2.status_code",
1094 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
1096 { &hf_mrcpv2_request_state,
1097 { "Request State", "mrcpv2.request_state",
1098 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
1100 { &hf_mrcpv2_Abort_Model,
1101 { "Abort-Model", "mrcpv2.Abort-Model",
1102 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1104 { &hf_mrcpv2_Abort_Phrase_Enrollment,
1105 { "Abort-Phrase-Enrollment", "mrcpv2.Abort-Phrase-Enrollment",
1106 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1108 { &hf_mrcpv2_Abort_Verification,
1109 { "Abort-Verification", "mrcpv2.Abort-Verification",
1110 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1112 { &hf_mrcpv2_Accept,
1113 { "Accept", "mrcpv2.Accept",
1114 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1116 { &hf_mrcpv2_Accept_Charset,
1117 { "Accept-Charset", "mrcpv2.Accept-Charset",
1118 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1120 { &hf_mrcpv2_Active_Request_Id_List,
1121 { "Active-Request-Id-List", "mrcpv2.Active-Request-Id-List",
1122 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1124 { &hf_mrcpv2_Adapt_Model,
1125 { "Adapt-Model", "mrcpv2.Adapt-Model",
1126 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1128 { &hf_mrcpv2_Audio_Fetch_Hint,
1129 { "Audio-Fetch-Hint", "mrcpv2.Audio-Fetch-Hint",
1130 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1132 { &hf_mrcpv2_Cache_Control,
1133 { "Cache-Control", "mrcpv2.Cache-Control",
1134 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1136 { &hf_mrcpv2_Cancel_If_Queue,
1137 { "Cancel-If-Queue", "mrcpv2.Cancel-If-Queue",
1138 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1140 { &hf_mrcpv2_Capture_On_Speech,
1141 { "Capture-On-Speech", "mrcpv2.Capture-On-Speech",
1142 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1144 { &hf_mrcpv2_Channel_Identifier,
1145 { "Channel-Identifier", "mrcpv2.Channel-Identifier",
1146 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1148 { &hf_mrcpv2_Clash_Threshold,
1149 { "Clash-Threshold", "mrcpv2.Clash-Threshold",
1150 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1152 { &hf_mrcpv2_Clear_Dtmf_Buffer,
1153 { "Clear-Dtmf-Buffer", "mrcpv2.Clear-Dtmf-Buffer",
1154 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1156 { &hf_mrcpv2_Completion_Cause,
1157 { "Completion-Cause", "mrcpv2.Completion-Cause",
1158 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1160 { &hf_mrcpv2_Completion_Reason,
1161 { "Completion-Reason", "mrcpv2.Completion-Reason",
1162 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1164 { &hf_mrcpv2_Confidence_Threshold,
1165 { "Confidence-Threshold", "mrcpv2.Confidence-Threshold",
1166 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1168 { &hf_mrcpv2_Confusable_Phrases_URI,
1169 { "Confusable-Phrases-URI", "mrcpv2.Confusable-Phrases-URI",
1170 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1172 { &hf_mrcpv2_Consistency_Threshold,
1173 { "Consistency-Threshold", "mrcpv2.Consistency-Threshold",
1174 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1176 { &hf_mrcpv2_Content_Base,
1177 { "Content-Base", "mrcpv2.Content-Base",
1178 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1180 { &hf_mrcpv2_Content_Encoding,
1181 { "Content-Encoding", "mrcpv2.Content-Encoding",
1182 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1184 { &hf_mrcpv2_Content_ID,
1185 { "Content-ID", "mrcpv2.Content-ID",
1186 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1188 { &hf_mrcpv2_Content_Length,
1189 { "Content-Length", "mrcpv2.Content-Length",
1190 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1192 { &hf_mrcpv2_Content_Location,
1193 { "Content-Location", "mrcpv2.Content-Location",
1194 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1196 { &hf_mrcpv2_Content_Type,
1197 { "Content-Type", "mrcpv2.Content-Type",
1198 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1200 { &hf_mrcpv2_Dtmf_Buffer_Time,
1201 { "Dtmf-Buffer-Time", "mrcpv2.Dtmf-Buffer-Time",
1202 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1204 { &hf_mrcpv2_Dtmf_Interdigit_Timeout,
1205 { "Dtmf-Interdigit-Timeout", "mrcpv2.Dtmf-Interdigit-Timeout",
1206 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1208 { &hf_mrcpv2_Dtmf_Term_Char,
1209 { "Dtmf-Term-Char", "mrcpv2.Dtmf-Term-Char",
1210 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1212 { &hf_mrcpv2_Dtmf_Term_Timeout,
1213 { "Dtmf-Term-Timeout", "mrcpv2.Dtmf-Term-Timeout",
1214 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1216 { &hf_mrcpv2_Early_No_Match,
1217 { "Early-No-Match", "mrcpv2.Early-No-Match",
1218 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1220 { &hf_mrcpv2_Enroll_Utterance,
1221 { "Enroll-Utterance", "mrcpv2.Enroll-Utterance",
1222 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1224 { &hf_mrcpv2_Failed_URI,
1225 { "Failed-URI", "mrcpv2.Failed-URI",
1226 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1228 { &hf_mrcpv2_Failed_URI_Cause,
1229 { "Failed-URI-Cause", "mrcpv2.Failed-URI-Cause",
1230 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1232 { &hf_mrcpv2_Fetch_Hint,
1233 { "Fetch-Hint", "mrcpv2.Fetch-Hint",
1234 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1236 { &hf_mrcpv2_Fetch_Timeout,
1237 { "Fetch-Timeout", "mrcpv2.Fetch-Timeout",
1238 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1240 { &hf_mrcpv2_Final_Silence,
1241 { "Final-Silence", "mrcpv2.Final-Silence",
1242 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1244 { &hf_mrcpv2_Hotword_Max_Duration,
1245 { "Hotword-Max-Duration", "mrcpv2.Hotword-Max-Duration",
1246 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1248 { &hf_mrcpv2_Hotword_Min_Duration,
1249 { "Hotword-Min-Duration", "mrcpv2.Hotword-Min-Duration",
1250 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1252 { &hf_mrcpv2_Input_Type,
1253 { "Input-Type", "mrcpv2.Input-Type",
1254 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1256 { &hf_mrcpv2_Input_Waveform_URI,
1257 { "Input-Waveform-URI", "mrcpv2.Input-Waveform-URI",
1258 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1260 { &hf_mrcpv2_Interpret_Text,
1261 { "Interpret-Text", "mrcpv2.Interpret-Text",
1262 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1264 { &hf_mrcpv2_Jump_Size,
1265 { "Jump-Size", "mrcpv2.Jump-Size",
1266 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1268 { &hf_mrcpv2_Kill_On_Barge_In,
1269 { "Kill-On-Barge-In", "mrcpv2.Kill-On-Barge-In",
1270 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1272 { &hf_mrcpv2_Lexicon_Search_Order,
1273 { "Lexicon-Search-Order", "mrcpv2.Lexicon-Search-Order",
1274 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1276 { &hf_mrcpv2_Load_Lexicon,
1277 { "Load-Lexicon", "mrcpv2.Load-Lexicon",
1278 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1280 { &hf_mrcpv2_Logging_Tag,
1281 { "Logging-Tag", "mrcpv2.Logging-Tag",
1282 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1284 { &hf_mrcpv2_Max_Time,
1285 { "Max-Time", "mrcpv2.Max-Time",
1286 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1288 { &hf_mrcpv2_Media_Type,
1289 { "Media-Type", "mrcpv2.Media-Type",
1290 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1292 { &hf_mrcpv2_Min_Verification_Score,
1293 { "Min-Verification-Score", "mrcpv2.Min-Verification-Score",
1294 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1296 { &hf_mrcpv2_N_Best_List_Length,
1297 { "N-Best-List-Length", "mrcpv2.N-Best-List-Length",
1298 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1300 { &hf_mrcpv2_New_Audio_Channel,
1301 { "New-Audio-Channel", "mrcpv2.New-Audio-Channel",
1302 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1304 { &hf_mrcpv2_New_Phrase_ID,
1305 { "New-Phrase-ID", "mrcpv2.New-Phrase-ID",
1306 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1308 { &hf_mrcpv2_No_Input_Timeout,
1309 { "No-Input-Timeout", "mrcpv2.No-Input-Timeout",
1310 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1312 { &hf_mrcpv2_Num_Max_Verification_Phrases,
1313 { "Num-Max-Verification-Phrases", "mrcpv2.Num-Max-Verification-Phrases",
1314 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1316 { &hf_mrcpv2_Num_Min_Consistent_Pronunciations,
1317 { "Num-Min-Consistent-Pronunciations", "mrcpv2.Num-Min-Consistent-Pronunciations",
1318 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1320 { &hf_mrcpv2_Num_Min_Verification_Phrases,
1321 { "Num-Min-Verification-Phrases", "mrcpv2.Num-Min-Verification-Phrases",
1322 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1324 { &hf_mrcpv2_Personal_Grammar_URI,
1325 { "Personal-Grammar-URI", "mrcpv2.Personal-Grammar-URI",
1326 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1328 { &hf_mrcpv2_Phrase_ID,
1329 { "Phrase-ID", "mrcpv2.Phrase-ID",
1330 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1332 { &hf_mrcpv2_Phrase_NL,
1333 { "Phrase-NL", "mrcpv2.Phrase-NL",
1334 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1336 { &hf_mrcpv2_Prosody_Contour,
1337 { "Prosody-Contour", "mrcpv2.Prosody-Contour",
1338 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1340 { &hf_mrcpv2_Prosody_Duration,
1341 { "Prosody-Duration", "mrcpv2.Prosody-Duration",
1342 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1344 { &hf_mrcpv2_Prosody_Pitch,
1345 { "Prosody-Pitch", "mrcpv2.Prosody-Pitch",
1346 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1348 { &hf_mrcpv2_Prosody_Range,
1349 { "Prosody-Range", "mrcpv2.Prosody-Range",
1350 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1352 { &hf_mrcpv2_Prosody_Rate,
1353 { "Prosody-Rate", "mrcpv2.Prosody-Rate",
1354 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1356 { &hf_mrcpv2_Prosody_Volume,
1357 { "Prosody-Volume", "mrcpv2.Prosody-Volume",
1358 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1360 { &hf_mrcpv2_Proxy_Sync_Id,
1361 { "Proxy-Sync-Id", "mrcpv2.Proxy-Sync-Id",
1362 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1364 { &hf_mrcpv2_Recognition_Mode,
1365 { "Recognition-Mode", "mrcpv2.Recognition-Mode",
1366 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1368 { &hf_mrcpv2_Recognition_Timeout,
1369 { "Recognition-Timeout", "mrcpv2.Recognition-Timeout",
1370 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1372 { &hf_mrcpv2_Recognizer_Context_Block,
1373 { "Recognizer-Context-Block", "mrcpv2.Recognizer-Context-Block",
1374 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1376 { &hf_mrcpv2_Record_URI,
1377 { "Record-URI", "mrcpv2.Record-URI",
1378 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1380 { &hf_mrcpv2_Repository_URI,
1381 { "Repository-URI", "mrcpv2.Repository-URI",
1382 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1384 { &hf_mrcpv2_Save_Best_Waveform,
1385 { "Save-Best-Waveform", "mrcpv2.Save-Best-Waveform",
1386 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1388 { &hf_mrcpv2_Save_Waveform,
1389 { "Save-Waveform", "mrcpv2.Save-Waveform",
1390 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1392 { &hf_mrcpv2_Sensitivity_Level,
1393 { "Sensitivity-Level", "mrcpv2.Sensitivity-Level",
1394 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1396 { &hf_mrcpv2_Set_Cookie,
1397 { "Set-Cookie", "mrcpv2.Set-Cookie",
1398 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1400 { &hf_mrcpv2_Speak_Length,
1401 { "Speak-Length", "mrcpv2.Speak-Length",
1402 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1404 { &hf_mrcpv2_Speak_Restart,
1405 { "Speak-Restart", "mrcpv2.Speak-Restart",
1406 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1408 { &hf_mrcpv2_Speaker_Profile,
1409 { "Speaker-Profile", "mrcpv2.Speaker-Profile",
1410 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1412 { &hf_mrcpv2_Speech_Complete_Timeout,
1413 { "Speech-Complete-Timeout", "mrcpv2.Speech-Complete-Timeout",
1414 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1416 { &hf_mrcpv2_Speech_Incomplete_Timeout,
1417 { "Speech-Incomplete-Timeout", "mrcpv2.Speech-Incomplete-Timeout",
1418 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1420 { &hf_mrcpv2_Speech_Language,
1421 { "Speech-Language", "mrcpv2.Speech-Language",
1422 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1424 { &hf_mrcpv2_Speech_Marker,
1425 { "Speech-Marker", "mrcpv2.Speech-Marker",
1426 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1428 { &hf_mrcpv2_Speed_Vs_Accuracy,
1429 { "Speed-Vs-Accuracy", "mrcpv2.Speed-Vs-Accuracy",
1430 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1432 { &hf_mrcpv2_Start_Input_Timers,
1433 { "Start-Input-Timers", "mrcpv2.Start-Input-Timers",
1434 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1436 { &hf_mrcpv2_Trim_Length,
1437 { "Trim-Length", "mrcpv2.Trim-Length",
1438 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1440 { &hf_mrcpv2_Vendor_Specific_Parameters,
1441 { "Vendor-Specific-Parameters", "mrcpv2.Vendor-Specific-Parameters",
1442 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1444 { &hf_mrcpv2_Ver_Buffer_Utterance,
1445 { "Ver-Buffer-Utterance", "mrcpv2.Ver-Buffer-Utterance",
1446 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1448 { &hf_mrcpv2_Verification_Mode,
1449 { "Verification-Mode", "mrcpv2.Verification-Mode",
1450 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1452 { &hf_mrcpv2_Voice_Age,
1453 { "Voice-Age", "mrcpv2.Voice-Age",
1454 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1456 { &hf_mrcpv2_Voice_Gender,
1457 { "Voice-Gender", "mrcpv2.Voice-Gender",
1458 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1460 { &hf_mrcpv2_Voice_Name,
1461 { "Voice-Name", "mrcpv2.Voice-Name",
1462 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1464 { &hf_mrcpv2_Voice_Variant,
1465 { "Voice-Variant", "mrcpv2.Voice-Variant",
1466 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1468 { &hf_mrcpv2_Voiceprint_Exists,
1469 { "Voiceprint-Exists", "mrcpv2.Voiceprint-Exists",
1470 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1472 { &hf_mrcpv2_Voiceprint_Identifier,
1473 { "Voiceprint-Identifier", "mrcpv2.Voiceprint-Identifier",
1474 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1476 { &hf_mrcpv2_Waveform_URI,
1477 { "Waveform-URI", "mrcpv2.Waveform-URI",
1478 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1480 { &hf_mrcpv2_Weight,
1481 { "Weight", "mrcpv2.Weight",
1482 FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL },
1486 static ei_register_info ei[] = {
1487 { &ei_mrcpv2_Content_Length_invalid, { "mrcpv2.Content-Length.invalid", PI_MALFORMED, PI_ERROR,
1488 "Content Length must be a string containing an integer", EXPFILL }}
1491 static int *ett[] = {
1492 &ett_mrcpv2,
1493 &ett_Request_Line,
1494 &ett_Response_Line,
1495 &ett_Event_Line,
1496 &ett_Status_Code
1499 proto_mrcpv2 = proto_register_protocol("Media Resource Control Protocol Version 2 (MRCPv2)", "MRCPv2", "mrcpv2");
1501 proto_register_field_array(proto_mrcpv2, hf, array_length(hf));
1502 proto_register_subtree_array(ett, array_length(ett));
1504 expert_mrcpv2 = expert_register_protocol(proto_mrcpv2);
1505 expert_register_field_array(expert_mrcpv2, ei, array_length(ei));
1507 mrcpv2_handle = register_dissector("mrcpv2", dissect_mrcpv2_tcp, proto_mrcpv2);
1510 void
1511 proto_reg_handoff_mrcpv2(void)
1513 dissector_add_uint_range_with_preference ("tcp.port", TCP_DEFAULT_RANGE, mrcpv2_handle);
1516 * Editor modelines
1518 * Local Variables:
1519 * c-basic-offset: 4
1520 * tab-width: 8
1521 * indent-tabs-mode: nil
1522 * End:
1524 * ex: set shiftwidth=4 tabstop=8 expandtab:
1525 * :indentSize=4:tabSize=8:noTabs=true: