Fix some aclocal warnings during autogen.sh
[obnox/wireshark/wip.git] / packet-wbxml.c
1 /* packet-wbxml.c
2  *
3  * Routines for WAP Binary XML dissection
4  * Copyright 2003, 2004, Olivier Biot.
5  *
6  * $Id: packet-wbxml.c,v 1.31 2004/03/17 19:50:05 obiot Exp $
7  *
8  * Refer to the AUTHORS file or the AUTHORS section in the man page
9  * for contacting the author(s) of this file.
10  *
11  * Ethereal - Network traffic analyzer
12  * By Gerald Combs <gerald@ethereal.com>
13  * Copyright 1998 Gerald Combs
14  *
15  * WAP Binary XML decoding functionality provided by Olivier Biot.
16  * 
17  * The WAP specifications are found at the WAP Forum:
18  * http://www.wapforum.org/what/Technical.htm
19  * 
20  * This program is free software; you can redistribute it and/or
21  * modify it under the terms of the GNU General Public License
22  * as published by the Free Software Foundation; either version 2
23  * of the License, or (at your option) any later version.
24  * 
25  * This program is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28  * GNU General Public License for more details.
29  * 
30  * You should have received a copy of the GNU General Public License
31  * along with this program; if not, write to the Free Software
32  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
33  */
34
35 /* Edit this file with 4-space tabulation */
36
37 #ifdef HAVE_CONFIG_H
38 # include "config.h"
39 #endif
40
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44
45 #include <glib.h>
46
47 #ifdef NEED_SNPRINTF_H
48 # include "snprintf.h"
49 #endif
50
51 #include <epan/packet.h>
52
53 /* We need the function tvb_get_guintvar() */
54 #include "packet-wap.h"
55
56 /* General-purpose debug logger.
57  * Requires double parentheses because of variable arguments of printf().
58  *
59  * Enable debug logging for WBXML by defining AM_FLAGS
60  * so that it contains "-DDEBUG_wbxml"
61  */
62 #ifdef DEBUG_wbxml
63 #define DebugLog(x) \
64         printf("%s:%u: ", __FILE__, __LINE__); \
65         printf x; \
66         fflush(stdout)
67 #else
68 #define DebugLog(x) ;
69 #endif
70
71 /* The code in this source file dissects the WAP Binary XML content,
72  * and if possible renders it. WBXML mappings are defined in the
73  * "wbxml_decoding" structure.
74  *
75  * NOTES:
76  *
77  *  - Some WBXML content is *not* backwards compatible across minor versions.
78  *    This painful remark is true for:
79  *      o  WMLC 1.0 with respect to later WMLC 1.x
80  *      o  All WV-CSP versions (never backwards compatible)
81  *    The only way of correctly rendering the WBXML is to let the end-user
82  *    choose from the possible renderings. This only aaplies to the case when
83  *    the WBXML DocType is not included in the WBXML header.
84  *
85  *  - Some WBXML content uses EXT_T_* in a non-tableref manner. This is the
86  *    case with WV-CSP 1.1 and up, where the index points to a value_string
87  *    containing WV-CSP specific token values. This is allowed as it is not
88  *    explicitly forbidden in the WBXML specifications. Hence the global token
89  *    map for content must also contain a function pointer if no tableref
90  *    string is used.
91  *
92  *  - Code page switches only apply to the following token. In the WBXML/1.x
93  *    ABNF notation, it can be proven that the switch_page can only precede
94  *    the following tokens:
95  *      o  stag      : TAG | LITERAL | LITERAL_A | LITERAL_C | LITERAL_AC
96  *      o  attr      : ATTRSTART | ATTRVALUE
97  *      o  extension : EXT_I | EXT_T | EXT
98  *    Code page switches are displayed in a separate column.
99  *
100  *  - The WBXML spec states that code pages are static to both the tag and the
101  *    attribute state parser. A SWITCH_PAGE within a state switches the code
102  *    page of the active state only. Note that code page 255 is reserved for
103  *    application-specific (read: testing) purposes.
104  *
105  *  - In order to render the XML content, recursion is inevitable at some
106  *    point (when a tag with content occurs in the content of a tag with
107  *    content). The code will however not recurse if this is not strictly
108  *    required (e.g., tag without content in the content of a tag with
109  *    content).
110  *
111  *  - I found it useful to display the XML nesting level as a first "column",
112  *    followed by the abbreviated WBXML token interpretation. When a mapping
113  *    is defined for the parsed WBXML content, then the XML rendering is
114  *    displayed with appropriate indentation (maximum nesting level = 255,
115  *    after which the nesting and level will safely roll-over to 0).
116  *
117  *  - The WAP Forum defines the order of precedence for finding out the
118  *    WBXML content type (same rules for charset) as follows:
119  *      1. Look in the Content-Type WSP header
120  *      2. Look in the WBXML header
121  *    Currently there is no means of using content type parameters:
122  *      o  Type=<some_type>
123  *      o  Charset=<charset_of_the_content>
124  *    So it is possible some WBXML content types are incorrectly parsed.
125  *    This would only be the case when the content type declaration in the
126  *    WSP Content-Type header would be different (or would have parameters
127  *    which are relevant to the WBXML decoding) from the content type
128  *    identifier specified in the WBXML header.
129  *    TODO: investigate this and provide correct decoding at all times.
130  */
131
132 typedef struct _value_valuestring {
133         guint32 value;
134         const value_string *valstrptr;
135 } value_valuestring;
136
137 /* Tries to match val against each element in the value_value_string array vvs.
138  * Returns the associated value_string ptr on a match, or NULL on failure. */
139 static const value_string *
140 val_to_valstr(guint32 val, const value_valuestring *vvs)
141 {
142   gint i = 0;
143
144   while (vvs[i].valstrptr) {
145         if (vvs[i].value == val)
146       return(vvs[i].valstrptr);
147       i++;
148   }
149
150   return(NULL);
151 }
152
153 /* Note on Token mapping
154  * ---------------------
155  *
156  * The WBXML dissector will try mapping the token decoding to their textual
157  * representation if the media type has a defined token representation. The
158  * following logic applies:
159  *
160  * a. Inspect the WBXML PublicID
161  *      This means that I need a list { PublicID, decoding }
162  *
163  * b. Inspect the literal media type
164  *      This requires a list { "media/type", discriminator, { decodings } }
165  *
166  *   b.1. Use a discriminator to choose an appropriate token mapping;
167  *      The disciminator needs a small number of bytes from the data tvbuf_t.
168  *
169  * else
170  *   b.2. Provide a list to the end-user with all possible token mappings.
171  *
172  * c. If none match then only show the tokens without mapping.
173  *
174  */
175
176 /* ext_t_func_ptr is a pointer to a function handling the EXT_T_i tokens:
177  *
178  * char * ext_t_function(tvbuff_t *tvb, guint32 value, guint32 strtbl);
179  */
180 typedef char * (* ext_t_func_ptr)(tvbuff_t *, guint32, guint32);
181
182 typedef struct _wbxml_decoding {
183     const char *name;
184     const char *abbrev;
185     ext_t_func_ptr ext_t[3];
186     const value_valuestring *global;
187     const value_valuestring *tags;
188     const value_valuestring *attrStart;
189     const value_valuestring *attrValue;
190 } wbxml_decoding;
191
192 typedef wbxml_decoding * (* discriminator_func_ptr)(tvbuff_t *);
193
194 /* For the decoding lists based on the known WBXML public ID */
195 typedef struct _wbxml_integer_list {
196     guint32 public_id;
197     const wbxml_decoding *map;
198 } wbxml_integer_list;
199
200 /* For the decoding lists on the literal content type */ 
201 typedef struct _wbxml_literal_list {
202     const char *content_type;
203     discriminator_func_ptr discriminator; /* TODO */
204     const wbxml_decoding *map;
205 } wbxml_literal_list;
206
207 /************************** Variable declarations **************************/
208
209
210 /* Initialize the protocol and registered fields */
211 static int proto_wbxml = -1;
212 static int hf_wbxml_version = -1;
213 static int hf_wbxml_public_id_known = -1;
214 static int hf_wbxml_public_id_literal = -1;
215 static int hf_wbxml_charset = -1;
216
217 /* Initialize the subtree pointers */
218 static gint ett_wbxml = -1;
219 static gint ett_wbxml_str_tbl = -1;
220 static gint ett_wbxml_content = -1;
221
222
223 /**************** WBXML related declarations and definitions ****************/
224
225
226 /* WBXML public ID mappings. For an up-to-date list, see
227  * http://www.openmobilealliance.org/tech/omna/ */
228 static const value_string vals_wbxml_public_ids[] = {
229         /* 0x00 = literal public identifier */
230         { 0x01, "Unknown / missing Public Identifier" },
231         { 0x02, "-//WAPFORUM//DTD WML 1.0//EN (WML 1.0)" },
232         { 0x03, "-//WAPFORUM//DTD WTA 1.0//EN (WTA Event 1.0) - Deprecated" },
233         { 0x04, "-//WAPFORUM//DTD WML 1.1//EN (WML 1.1)" },
234         { 0x05, "-//WAPFORUM//DTD SI 1.0//EN (Service Indication 1.0)" },
235         { 0x06, "-//WAPFORUM//DTD SL 1.0//EN (Service Loading 1.0)" },
236         { 0x07, "-//WAPFORUM//DTD CO 1.0//EN (Cache Operation 1.0)" },
237         { 0x08, "-//WAPFORUM//DTD CHANNEL 1.0//EN (Channel 1.1)" },
238         { 0x09, "-//WAPFORUM//DTD WML 1.2//EN (WML 1.2)" },
239         { 0x0a, "-//WAPFORUM//DTD WML 1.3//EN (WML 1.3)" },
240         { 0x0b, "-//WAPFORUM//DTD PROV 1.0//EN (Provisioning 1.0)" },
241         { 0x0c, "-//WAPFORUM//DTD WTA-WML 1.2//EN (WTA-WML 1.2)" },
242         { 0x0d, "-//WAPFORUM//DTD EMN 1.0//EN (Email Notification 1.0)" },
243         { 0x0e, "-//WAPFORUM//DTD DRMREL 1.0//EN (DRMREL 1.0)" },
244         { 0x0f, "-//WIRELESSVILLAGE//DTD CSP 1.0//EN"
245                 " (Wireless Village Client-Server Protocol DTD v1.0)" },
246         { 0x10, "-//WIRELESSVILLAGE//DTD CSP 1.1//EN"
247                 " (Wireless Village Client-Server Protocol DTD v1.1)" },
248
249         /* Registered values - www.syncml.org */
250         { 0x0fd1, "-//SYNCML//DTD SyncML 1.0//EN (SyncML 1.0)" },
251         { 0x0fd3, "-//SYNCML//DTD SyncML 1.1//EN (SyncML 1.1)" },
252
253         /* Registered values - www.wapforum.org/wina/ */
254         { 0x1100, "-//PHONE.COM//DTD ALERT 1.0//EN" },
255         { 0x1101, "-//PHONE.COM//DTD CACHE-OPERATION 1.0//EN" },
256         { 0x1102, "-//PHONE.COM//DTD SIGNAL 1.0//EN" },
257         { 0x1103, "-//PHONE.COM//DTD LIST 1.0//EN" },
258         { 0x1104, "-//PHONE.COM//DTD LISTCMD 1.0//EN" },
259         { 0x1105, "-//PHONE.COM//DTD CHANNEL 1.0//EN" },
260         { 0x1106, "-//PHONE.COM//DTD MMC 1.0//EN" },
261         { 0x1107, "-//PHONE.COM//DTD BEARER-CHOICE 1.0//EN" },
262         { 0x1108, "-//PHONE.COM//DTD WML 1.1//EN (WML+ 1.1)" },
263         { 0x1109, "-//PHONE.COM//DTD CHANNEL 1.1//EN" },
264         { 0x110a, "-//PHONE.COM//DTD LIST 1.1//EN" },
265         { 0x110b, "-//PHONE.COM//DTD LISTCMD 1.1//EN" },
266         { 0x110c, "-//PHONE.COM//DTD MMC 1.1//EN" },
267         { 0x110d, "-//PHONE.COM//DTD WML 1.3//EN (WML+ 1.3)" },
268         { 0x110e, "-//PHONE.COM//DTD MMC 2.0//EN" },
269         /* 0x110F -- 0x11FF: unassigned */
270         { 0x1200, "-//3GPP2.COM//DTD IOTA 1.0//EN" },
271         
272         { 0x00, NULL }
273 };
274
275 static const value_string vals_wbxml_versions[] = {
276         { 0x00, "1.0" },        /* WAP-104-WBXML */
277         { 0x01, "1.1" },        /* WAP-135-WBXML */
278         { 0x02, "1.2" },        /* WAP-154-WBXML */
279         { 0x03, "1.3" },        /* WAP-192-WBXML */
280         
281         { 0x00, NULL }
282 };
283
284 /* WBXML 1.0 global tokens: WAP-104-WBXML
285  * Same token mapping as in vals_wbxml1x_global_tokens, but:
286  *   { 0xC3, "RESERVED_2" }
287  */
288
289 /* WBXML 1.x (x>0) global tokens: WAP-135-WBXML, WAP-154-WBXML, WAP-192-WBXML
290  */
291 static const value_string vals_wbxml1x_global_tokens[] = {
292         { 0x00, "SWITCH_PAGE" },
293         { 0x01, "END" },
294         { 0x02, "ENTITY" },
295         { 0x03, "STR_I" },
296         { 0x04, "LITERAL" },
297
298         { 0x40, "EXT_I_0" },
299         { 0x41, "EXT_I_1" },
300         { 0x42, "EXT_I_2" },
301         { 0x43, "PI" },
302         { 0x44, "LITERAL_C" },
303
304         { 0x80, "EXT_T_0" },
305         { 0x81, "EXT_T_1" },
306         { 0x82, "EXT_T_2" },
307         { 0x83, "STR_T" },
308         { 0x84, "LITERAL_A" },
309
310         { 0xC0, "EXT_0" },
311         { 0xC1, "EXT_1" },
312         { 0xC2, "EXT_2" },
313         { 0xC3, "OPAQUE" },
314         { 0xC4, "LITERAL_AC" },
315
316         { 0x00, NULL }
317 };
318
319
320
321
322
323 /********************** WBXML token mapping definition **********************/
324
325 /*
326  * NOTE: Please make sure the Attribute Start values all contain an equal sign
327  *       even in cases where they do not contain the start of an Attribute
328  *       Value.
329  */
330
331
332 /* WML 1.0
333  * 
334  * Wireless Markup Language
335  ***************************************/
336 static char *
337 ext_t_0_wml_10(tvbuff_t *tvb, guint32 value, guint32 str_tbl)
338 {
339     gint str_len = tvb_strsize (tvb, str_tbl + value);
340     char *str = g_strdup_printf("Variable substitution - escaped: '%s'",
341             tvb_get_ptr(tvb, str_tbl + value, str_len));
342     return str;
343 }
344
345 static char *
346 ext_t_1_wml_10(tvbuff_t *tvb, guint32 value, guint32 str_tbl)
347 {
348     gint str_len = tvb_strsize (tvb, str_tbl + value);
349     char *str = g_strdup_printf("Variable substitution - unescaped: '%s'",
350             tvb_get_ptr(tvb, str_tbl + value, str_len));
351     return str;
352 }
353
354 static char *
355 ext_t_2_wml_10(tvbuff_t *tvb, guint32 value, guint32 str_tbl)
356 {
357     gint str_len = tvb_strsize (tvb, str_tbl + value);
358     char *str = g_strdup_printf("Variable substitution - no transformation: '%s'",
359             tvb_get_ptr(tvb, str_tbl + value, str_len));
360     return str;
361 }
362 /*****   Global extension tokens   *****/
363 static const value_string wbxml_wmlc10_global_cp0[] = {
364         { 0x40, "Variable substitution - escaped" },
365         { 0x41, "Variable substitution - unescaped" },
366         { 0x42, "Variable substitution - no transformation" },
367         { 0x80, "Variable substitution - escaped" },
368         { 0x81, "Variable substitution - unescaped" },
369         { 0x82, "Variable substitution - no transformation" },
370         { 0xC0, "Reserved" },
371         { 0xC1, "Reserved" },
372         { 0xC2, "Reserved" },
373
374         { 0x00, NULL }
375 };
376
377 /*****         Tag tokens          *****/
378 static const value_string wbxml_wmlc10_tags_cp0[] = {
379         /* 0x00 -- 0x04 GLOBAL */
380         /* 0x05 -- 0x21 */
381         { 0x22, "A" },
382         { 0x23, "ACCESS" },
383         { 0x24, "B" },
384         { 0x25, "BIG" },
385         { 0x26, "BR" },
386         { 0x27, "CARD" },
387         { 0x28, "DO" },
388         { 0x29, "EM" },
389         { 0x2A, "FIELDSET" },
390         { 0x2B, "GO" },
391         { 0x2C, "HEAD" },
392         { 0x2D, "I" },
393         { 0x2E, "IMG" },
394         { 0x2F, "INPUT" },
395         { 0x30, "META" },
396         { 0x31, "NOOP" },
397         { 0x32, "PREV" },
398         { 0x33, "ONEVENT" },
399         { 0x34, "OPTGROUP" },
400         { 0x35, "OPTION" },
401         { 0x36, "REFRESH" },
402         { 0x37, "SELECT" },
403         { 0x38, "SMALL" },
404         { 0x39, "STRONG" },
405         { 0x3A, "TAB" },
406         { 0x3B, "TEMPLATE" },
407         { 0x3C, "TIMER" },
408         { 0x3D, "U" },
409         { 0x3E, "VAR" },
410         { 0x3F, "WML" },
411
412         { 0x00, NULL }
413 };
414
415 /*****    Attribute Start tokens   *****/
416 static const value_string wbxml_wmlc10_attrStart_cp0[] = {
417         /* 0x00 -- 0x04 GLOBAL */
418         { 0x05, "ACCEPT-CHARSET=" },
419         { 0x06, "ALIGN='BOTTOM'" },
420         { 0x07, "ALIGN='CENTER'" },
421         { 0x08, "ALIGN='LEFT'" },
422         { 0x09, "ALIGN='MIDDLE'" },
423         { 0x0A, "ALIGN='RIGHT'" },
424         { 0x0B, "ALIGN='TOP'" },
425         { 0x0C, "ALT=" },
426         { 0x0D, "CONTENT=" },
427         { 0x0E, "DEFAULT=" },
428         { 0x0F, "DOMAIN=" },
429         { 0x10, "EMPTYOK='FALSE'" },
430         { 0x11, "EMPTYOK='TRUE'" },
431         { 0x12, "FORMAT=" },
432         { 0x13, "HEIGHT=" },
433         { 0x14, "HSPACE=" },
434         { 0x15, "IDEFAULT=" },
435         { 0x16, "IKEY=" },
436         { 0x17, "KEY=" },
437         { 0x18, "LABEL=" },
438         { 0x19, "LOCALSRC=" },
439         { 0x1A, "MAXLENGTH=" },
440         { 0x1B, "METHOD='GET'" },
441         { 0x1C, "METHOD='POST'" },
442         { 0x1D, "MODE='NOWRAP'" },
443         { 0x1E, "MODE='WRAP'" },
444         { 0x1F, "MULTIPLE='FALSE'" },
445         { 0x20, "MULTIPLE='TRUE'" },
446         { 0x21, "NAME=" },
447         { 0x22, "NEWCONTEXT='FALSE'" },
448         { 0x23, "NEWCONTEXT='TRUE'" },
449         { 0x24, "ONCLICK=" },
450         { 0x25, "ONENTERBACKWARD=" },
451         { 0x26, "ONENTERFORWARD=" },
452         { 0x27, "ONTIMER=" },
453         { 0x28, "OPTIONAL='FALSE'" },
454         { 0x29, "OPTIONAL='TRUE'" },
455         { 0x2A, "PATH=" },
456         { 0x2B, "POSTDATA=" },
457         { 0x2C, "PUBLIC='FALSE'" },
458         { 0x2D, "PUBLIC='TRUE'" },
459         { 0x2E, "SCHEME=" },
460         { 0x2F, "SENDREFERER='FALSE'" },
461         { 0x30, "SENDREFERER='TRUE'" },
462         { 0x31, "SIZE=" },
463         { 0x32, "SRC=" },
464         { 0x33, "STYLE='LIST'" },
465         { 0x34, "STYLE='SET'" },
466         { 0x35, "TABINDEX=" },
467         { 0x36, "TITLE=" },
468         { 0x37, "TYPE=" },
469         { 0x38, "TYPE='ACCEPT'" },
470         { 0x39, "TYPE='DELETE'" },
471         { 0x3A, "TYPE='HELP'" },
472         { 0x3B, "TYPE='PASSWORD'" },
473         { 0x3C, "TYPE='ONCLICK'" },
474         { 0x3D, "TYPE='ONENTERBACKWARD'" },
475         { 0x3E, "TYPE='ONENTERFORWARD'" },
476         { 0x3F, "TYPE='ONTIMER'" },
477         /* 0x40 -- 0x44 GLOBAL */
478         { 0x45, "TYPE='OPTIONS'" },
479         { 0x46, "TYPE='PREV'" },
480         { 0x47, "TYPE='RESET'" },
481         { 0x48, "TYPE='TEXT'" },
482         { 0x49, "TYPE='vnd.'" },
483         { 0x4A, "URL=" },
484         { 0x4B, "URL='http://'" },
485         { 0x4C, "URL='https://'" },
486         { 0x4D, "USER-AGENT=" },
487         { 0x4E, "VALUE=" },
488         { 0x4F, "VSPACE=" },
489         { 0x50, "WIDTH=" },
490         { 0x51, "xml:lang=" },
491
492         { 0x00, NULL }
493 };
494
495 /*****    Attribute Value tokens   *****/
496 static const value_string wbxml_wmlc10_attrValue_cp0[] = {
497         /* 0x80 -- 0x84 GLOBAL */
498         { 0x85, "'.com/'" },
499         { 0x86, "'.edu/'" },
500         { 0x87, "'.net/'" },
501         { 0x88, "'.org/'" },
502         { 0x89, "'ACCEPT'" },
503         { 0x8A, "'BOTTOM'" },
504         { 0x8B, "'CLEAR'" },
505         { 0x8C, "'DELETE'" },
506         { 0x8D, "'HELP'" },
507         { 0x8E, "'http://'" },
508         { 0x8F, "'http://www.'" },
509         { 0x90, "'https://'" },
510         { 0x91, "'https://www.'" },
511         { 0x92, "'LIST'" },
512         { 0x93, "'MIDDLE'" },
513         { 0x94, "'NOWRAP'" },
514         { 0x95, "'ONCLICK'" },
515         { 0x96, "'ONENTERBACKWARD'" },
516         { 0x97, "'ONENTERFORWARD'" },
517         { 0x98, "'ONTIMER'" },
518         { 0x99, "'OPTIONS'" },
519         { 0x9A, "'PASSWORD'" },
520         { 0x9B, "'RESET'" },
521         { 0x9C, "'SET'" },
522         { 0x9D, "'TEXT'" },
523         { 0x9E, "'TOP'" },
524         { 0x9F, "'UNKNOWN'" },
525         { 0xA0, "'WRAP'" },
526         { 0xA1, "'www.'" },
527
528         { 0x00, NULL }
529 };
530
531 /***** Token code page aggregation *****/
532 static const value_valuestring wbxml_wmlc10_global[] = {
533         { 0, wbxml_wmlc10_global_cp0 },
534         { 0, NULL }
535 };
536
537 static const value_valuestring wbxml_wmlc10_tags[] = {
538         { 0, wbxml_wmlc10_tags_cp0 },
539         { 0, NULL }
540 };
541
542 static const value_valuestring wbxml_wmlc10_attrStart[] = {
543         { 0, wbxml_wmlc10_attrStart_cp0 },
544         { 0, NULL }
545 };
546
547 static const value_valuestring wbxml_wmlc10_attrValue[] = {
548         { 0, wbxml_wmlc10_attrValue_cp0 },
549         { 0, NULL }
550 };
551
552 static const wbxml_decoding decode_wmlc_10 = {
553     "Wireless Markup Language 1.0",
554     "WML 1.0",
555     { ext_t_0_wml_10, ext_t_1_wml_10, ext_t_2_wml_10 },
556     wbxml_wmlc10_global,
557     wbxml_wmlc10_tags,
558     wbxml_wmlc10_attrStart,
559     wbxml_wmlc10_attrValue
560 };
561
562
563
564
565 /* WML 1.1
566  * 
567  * Wireless Markup Language
568  ***************************************/
569
570 /*****   Global extension tokens   *****/
571 /* Same as in WML 1.0 */
572
573 /*****         Tag tokens          *****/
574 static const value_string wbxml_wmlc11_tags_cp0[] = {
575         /* 0x00 -- 0x04 GLOBAL */
576         /* 0x05 -- 0x1B */
577         { 0x1C, "a" },
578         { 0x1D, "td" },
579         { 0x1E, "tr" },
580         { 0x1F, "table" },
581         { 0x20, "p" },
582         { 0x21, "postfield" },
583         { 0x22, "anchor" },
584         { 0x23, "access" },
585         { 0x24, "b" },
586         { 0x25, "big" },
587         { 0x26, "br" },
588         { 0x27, "card" },
589         { 0x28, "do" },
590         { 0x29, "em" },
591         { 0x2A, "fieldset" },
592         { 0x2B, "go" },
593         { 0x2C, "head" },
594         { 0x2D, "i" },
595         { 0x2E, "img" },
596         { 0x2F, "input" },
597         { 0x30, "meta" },
598         { 0x31, "noop" },
599         { 0x32, "prev" },
600         { 0x33, "onevent" },
601         { 0x34, "optgroup" },
602         { 0x35, "option" },
603         { 0x36, "refresh" },
604         { 0x37, "select" },
605         { 0x38, "small" },
606         { 0x39, "strong" },
607         /* 0x3A */
608         { 0x3B, "template" },
609         { 0x3C, "timer" },
610         { 0x3D, "u" },
611         { 0x3E, "setvar" },
612         { 0x3F, "wml" },
613
614         { 0x00, NULL }
615 };
616
617 /*****    Attribute Start tokens   *****/
618 static const value_string wbxml_wmlc11_attrStart_cp0[] = {
619         /* 0x00 -- 0x04 GLOBAL */
620         { 0x05, "accept-charset=" },
621         { 0x06, "align='bottom'" },
622         { 0x07, "align='center'" },
623         { 0x08, "align='left'" },
624         { 0x09, "align='middle'" },
625         { 0x0A, "align='right'" },
626         { 0x0B, "align='top'" },
627         { 0x0C, "alt=" },
628         { 0x0D, "content=" },
629         /* 0x0E */
630         { 0x0F, "domain=" },
631         { 0x10, "emptyok='false'" },
632         { 0x11, "emptyok='true'" },
633         { 0x12, "format=" },
634         { 0x13, "height=" },
635         { 0x14, "hspace=" },
636         { 0x15, "ivalue=" },
637         { 0x16, "iname=" },
638         /* 0x17 */
639         { 0x18, "label=" },
640         { 0x19, "localsrc=" },
641         { 0x1A, "maxlength=" },
642         { 0x1B, "method='get'" },
643         { 0x1C, "method='post'" },
644         { 0x1D, "mode='nowrap'" },
645         { 0x1E, "mode='wrap'" },
646         { 0x1F, "multiple='false'" },
647         { 0x20, "multiple='true'" },
648         { 0x21, "name=" },
649         { 0x22, "newcontext='false'" },
650         { 0x23, "newcontext='true'" },
651         { 0x24, "onpick=" },
652         { 0x25, "onenterbackward=" },
653         { 0x26, "onenterforward=" },
654         { 0x27, "ontimer=" },
655         { 0x28, "optional='false'" },
656         { 0x29, "optional='true'" },
657         { 0x2A, "path=" },
658         /* 0x2B -- 0x2D */
659         { 0x2E, "scheme=" },
660         { 0x2F, "sendreferer='false'" },
661         { 0x30, "sendreferer='true'" },
662         { 0x31, "size=" },
663         { 0x32, "src=" },
664         { 0x33, "ordered='false'" },
665         { 0x34, "ordered='true'" },
666         { 0x35, "tabindex=" },
667         { 0x36, "title=" },
668         { 0x37, "type=" },
669         { 0x38, "type='accept'" },
670         { 0x39, "type='delete'" },
671         { 0x3A, "type='help'" },
672         { 0x3B, "type='password'" },
673         { 0x3C, "type='onpick'" },
674         { 0x3D, "type='onenterbackward'" },
675         { 0x3E, "type='onenterforward'" },
676         { 0x3F, "type='ontimer'" },
677         /* 0x40 -- 0x44 GLOBAL */
678         { 0x45, "type='options'" },
679         { 0x46, "type='prev'" },
680         { 0x47, "type='reset'" },
681         { 0x48, "type='text'" },
682         { 0x49, "type='vnd.'" },
683         { 0x4A, "href=" },
684         { 0x4B, "href='http://'" },
685         { 0x4C, "href='https://'" },
686         { 0x4D, "value=" },
687         { 0x4E, "vspace=" },
688         { 0x4F, "width=" },
689         { 0x50, "xml:lang=" },
690         /* 0x51 */
691         { 0x52, "align=" },
692         { 0x53, "columns=" },
693         { 0x54, "class=" },
694         { 0x55, "id=" },
695         { 0x56, "forua='false'" },
696         { 0x57, "forua='true'" },
697         { 0x58, "src='http://'" },
698         { 0x59, "src='https://'" },
699         { 0x5A, "http-equiv=" },
700         { 0x5B, "http-equiv='Content-Type'" },
701         { 0x5C, "content='application/vnd.wap.wmlc;charset='" },
702         { 0x5D, "http-equiv='Expires'" },
703
704         { 0x00, NULL }
705 };
706
707 /*****    Attribute Value tokens   *****/
708 static const value_string wbxml_wmlc11_attrValue_cp0[] = {
709         /* 0x80 -- 0x84 GLOBAL */
710         { 0x85, "'.com/'" },
711         { 0x86, "'.edu/'" },
712         { 0x87, "'.net/'" },
713         { 0x88, "'.org/'" },
714         { 0x89, "'accept'" },
715         { 0x8A, "'bottom'" },
716         { 0x8B, "'clear'" },
717         { 0x8C, "'delete'" },
718         { 0x8D, "'help'" },
719         { 0x8E, "'http://'" },
720         { 0x8F, "'http://www.'" },
721         { 0x90, "'https://'" },
722         { 0x91, "'https://www.'" },
723         /* 0x92 */
724         { 0x93, "'middle'" },
725         { 0x94, "'nowrap'" },
726         { 0x95, "'onpick'" },
727         { 0x96, "'onenterbackward'" },
728         { 0x97, "'onenterforward'" },
729         { 0x98, "'ontimer'" },
730         { 0x99, "'options'" },
731         { 0x9A, "'password'" },
732         { 0x9B, "'reset'" },
733         /* 0x9C */
734         { 0x9D, "'text'" },
735         { 0x9E, "'top'" },
736         { 0x9F, "'unknown'" },
737         { 0xA0, "'wrap'" },
738         { 0xA1, "'www.'" },
739
740         { 0x00, NULL }
741 };
742
743 /***** Token code page aggregation *****/
744 static const value_valuestring wbxml_wmlc11_global[] = {
745         { 0, wbxml_wmlc10_global_cp0 }, /* Same as WML 1.0 */
746         { 0, NULL }
747 };
748
749 static const value_valuestring wbxml_wmlc11_tags[] = {
750         { 0, wbxml_wmlc11_tags_cp0 },
751         { 0, NULL }
752 };
753
754 static const value_valuestring wbxml_wmlc11_attrStart[] = {
755         { 0, wbxml_wmlc11_attrStart_cp0 },
756         { 0, NULL }
757 };
758
759 static const value_valuestring wbxml_wmlc11_attrValue[] = {
760         { 0, wbxml_wmlc11_attrValue_cp0 },
761         { 0, NULL }
762 };
763
764 static const wbxml_decoding decode_wmlc_11 = {
765     "Wireless Markup Language 1.1",
766     "WML 1.1",
767     { ext_t_0_wml_10, ext_t_1_wml_10, ext_t_2_wml_10 },
768     wbxml_wmlc11_global,
769     wbxml_wmlc11_tags,
770     wbxml_wmlc11_attrStart,
771     wbxml_wmlc11_attrValue
772 };
773
774
775
776
777
778 /* WML 1.2
779  * 
780  * Wireless Markup Language
781  ***************************************/
782
783 /*****   Global extension tokens   *****/
784 /* Same as in WML 1.0 */
785
786 /*****         Tag tokens          *****/
787 static const value_string wbxml_wmlc12_tags_cp0[] = {
788         /* 0x00 -- 0x04 GLOBAL */
789         /* 0x05 -- 0x1A */
790         { 0x1B, "pre" },
791         { 0x1C, "a" },
792         { 0x1D, "td" },
793         { 0x1E, "tr" },
794         { 0x1F, "table" },
795         { 0x20, "p" },
796         { 0x21, "postfield" },
797         { 0x22, "anchor" },
798         { 0x23, "access" },
799         { 0x24, "b" },
800         { 0x25, "big" },
801         { 0x26, "br" },
802         { 0x27, "card" },
803         { 0x28, "do" },
804         { 0x29, "em" },
805         { 0x2A, "fieldset" },
806         { 0x2B, "go" },
807         { 0x2C, "head" },
808         { 0x2D, "i" },
809         { 0x2E, "img" },
810         { 0x2F, "input" },
811         { 0x30, "meta" },
812         { 0x31, "noop" },
813         { 0x32, "prev" },
814         { 0x33, "onevent" },
815         { 0x34, "optgroup" },
816         { 0x35, "option" },
817         { 0x36, "refresh" },
818         { 0x37, "select" },
819         { 0x38, "small" },
820         { 0x39, "strong" },
821         /* 0x3A */
822         { 0x3B, "template" },
823         { 0x3C, "timer" },
824         { 0x3D, "u" },
825         { 0x3E, "setvar" },
826         { 0x3F, "wml" },
827
828         { 0x00, NULL }
829 };
830
831 /*****    Attribute Start tokens   *****/
832 static const value_string wbxml_wmlc12_attrStart_cp0[] = {
833         /* 0x00 -- 0x04 GLOBAL */
834         { 0x05, "accept-charset=" },
835         { 0x06, "align='bottom'" },
836         { 0x07, "align='center'" },
837         { 0x08, "align='left'" },
838         { 0x09, "align='middle'" },
839         { 0x0A, "align='right'" },
840         { 0x0B, "align='top'" },
841         { 0x0C, "alt=" },
842         { 0x0D, "content=" },
843         /* 0x0E */
844         { 0x0F, "domain=" },
845         { 0x10, "emptyok='false'" },
846         { 0x11, "emptyok='true'" },
847         { 0x12, "format=" },
848         { 0x13, "height=" },
849         { 0x14, "hspace=" },
850         { 0x15, "ivalue=" },
851         { 0x16, "iname=" },
852         /* 0x17 */
853         { 0x18, "label=" },
854         { 0x19, "localsrc=" },
855         { 0x1A, "maxlength=" },
856         { 0x1B, "method='get'" },
857         { 0x1C, "method='post'" },
858         { 0x1D, "mode='nowrap'" },
859         { 0x1E, "mode='wrap'" },
860         { 0x1F, "multiple='false'" },
861         { 0x20, "multiple='true'" },
862         { 0x21, "name=" },
863         { 0x22, "newcontext='false'" },
864         { 0x23, "newcontext='true'" },
865         { 0x24, "onpick=" },
866         { 0x25, "onenterbackward=" },
867         { 0x26, "onenterforward=" },
868         { 0x27, "ontimer=" },
869         { 0x28, "optional='false'" },
870         { 0x29, "optional='true'" },
871         { 0x2A, "path=" },
872         /* 0x2B -- 0x2D */
873         { 0x2E, "scheme=" },
874         { 0x2F, "sendreferer='false'" },
875         { 0x30, "sendreferer='true'" },
876         { 0x31, "size=" },
877         { 0x32, "src=" },
878         { 0x33, "ordered='false'" },
879         { 0x34, "ordered='true'" },
880         { 0x35, "tabindex=" },
881         { 0x36, "title=" },
882         { 0x37, "type=" },
883         { 0x38, "type='accept'" },
884         { 0x39, "type='delete'" },
885         { 0x3A, "type='help'" },
886         { 0x3B, "type='password'" },
887         { 0x3C, "type='onpick'" },
888         { 0x3D, "type='onenterbackward'" },
889         { 0x3E, "type='onenterforward'" },
890         { 0x3F, "type='ontimer'" },
891         /* 0x40 -- 0x44 GLOBAL */
892         { 0x45, "type='options'" },
893         { 0x46, "type='prev'" },
894         { 0x47, "type='reset'" },
895         { 0x48, "type='text'" },
896         { 0x49, "type='vnd.'" },
897         { 0x4A, "href=" },
898         { 0x4B, "href='http://'" },
899         { 0x4C, "href='https://'" },
900         { 0x4D, "value=" },
901         { 0x4E, "vspace=" },
902         { 0x4F, "width=" },
903         { 0x50, "xml:lang=" },
904         /* 0x51 */
905         { 0x52, "align=" },
906         { 0x53, "columns=" },
907         { 0x54, "class=" },
908         { 0x55, "id=" },
909         { 0x56, "forua='false'" },
910         { 0x57, "forua='true'" },
911         { 0x58, "src='http://'" },
912         { 0x59, "src='https://'" },
913         { 0x5A, "http-equiv=" },
914         { 0x5B, "http-equiv='Content-Type'" },
915         { 0x5C, "content='application/vnd.wap.wmlc;charset='" },
916         { 0x5D, "http-equiv='Expires'" },
917         { 0x5E, "accesskey=" },
918         { 0x5F, "enctype=" },
919         { 0x60, "enctype='application/x-www-form-urlencoded'" },
920         { 0x61, "enctype='multipart/form-data'" },
921
922         { 0x00, NULL }
923 };
924
925 /*****    Attribute Value tokens   *****/
926 /* Same as in WML 1.1 */
927
928 /***** Token code page aggregation *****/
929 static const value_valuestring wbxml_wmlc12_global[] = {
930         { 0, wbxml_wmlc10_global_cp0 }, /* Same as WML 1.0 */
931         { 0, NULL }
932 };
933
934 static const value_valuestring wbxml_wmlc12_tags[] = {
935         { 0, wbxml_wmlc12_tags_cp0 },
936         { 0, NULL }
937 };
938
939 static const value_valuestring wbxml_wmlc12_attrStart[] = {
940         { 0, wbxml_wmlc12_attrStart_cp0 },
941         { 0, NULL }
942 };
943
944 static const value_valuestring wbxml_wmlc12_attrValue[] = {
945         { 0, wbxml_wmlc11_attrValue_cp0 }, /* Same as WML 1.1 */
946         { 0, NULL }
947 };
948
949 static const wbxml_decoding decode_wmlc_12 = {
950     "Wireless Markup Language 1.2",
951     "WML 1.2",
952     { ext_t_0_wml_10, ext_t_1_wml_10, ext_t_2_wml_10 },
953     wbxml_wmlc12_global,
954     wbxml_wmlc12_tags,
955     wbxml_wmlc12_attrStart,
956     wbxml_wmlc12_attrValue
957 };
958
959
960
961
962
963 /* WML 1.3
964  * 
965  * Wireless Markup Language
966  ***************************************/
967
968 /*****   Global extension tokens   *****/
969 /* Same as in WML 1.0 */
970
971 /*****         Tag tokens          *****/
972 /* Same as in WML 1.2 */
973
974 /*****    Attribute Start tokens   *****/
975 static const value_string wbxml_wmlc13_attrStart_cp0[] = {
976         /* 0x00 -- 0x04 GLOBAL */
977         { 0x05, "accept-charset=" },
978         { 0x06, "align='bottom'" },
979         { 0x07, "align='center'" },
980         { 0x08, "align='left'" },
981         { 0x09, "align='middle'" },
982         { 0x0A, "align='right'" },
983         { 0x0B, "align='top'" },
984         { 0x0C, "alt=" },
985         { 0x0D, "content=" },
986         /* 0x0E */
987         { 0x0F, "domain=" },
988         { 0x10, "emptyok='false'" },
989         { 0x11, "emptyok='true'" },
990         { 0x12, "format=" },
991         { 0x13, "height=" },
992         { 0x14, "hspace=" },
993         { 0x15, "ivalue=" },
994         { 0x16, "iname=" },
995         /* 0x17 */
996         { 0x18, "label=" },
997         { 0x19, "localsrc=" },
998         { 0x1A, "maxlength=" },
999         { 0x1B, "method='get'" },
1000         { 0x1C, "method='post'" },
1001         { 0x1D, "mode='nowrap'" },
1002         { 0x1E, "mode='wrap'" },
1003         { 0x1F, "multiple='false'" },
1004         { 0x20, "multiple='true'" },
1005         { 0x21, "name=" },
1006         { 0x22, "newcontext='false'" },
1007         { 0x23, "newcontext='true'" },
1008         { 0x24, "onpick=" },
1009         { 0x25, "onenterbackward=" },
1010         { 0x26, "onenterforward=" },
1011         { 0x27, "ontimer=" },
1012         { 0x28, "optional='false'" },
1013         { 0x29, "optional='true'" },
1014         { 0x2A, "path=" },
1015         /* 0x2B -- 0x2D */
1016         { 0x2E, "scheme=" },
1017         { 0x2F, "sendreferer='false'" },
1018         { 0x30, "sendreferer='true'" },
1019         { 0x31, "size=" },
1020         { 0x32, "src=" },
1021         { 0x33, "ordered='false'" },
1022         { 0x34, "ordered='true'" },
1023         { 0x35, "tabindex=" },
1024         { 0x36, "title=" },
1025         { 0x37, "type=" },
1026         { 0x38, "type='accept'" },
1027         { 0x39, "type='delete'" },
1028         { 0x3A, "type='help'" },
1029         { 0x3B, "type='password'" },
1030         { 0x3C, "type='onpick'" },
1031         { 0x3D, "type='onenterbackward'" },
1032         { 0x3E, "type='onenterforward'" },
1033         { 0x3F, "type='ontimer'" },
1034         /* 0x40 -- 0x44 GLOBAL */
1035         { 0x45, "type='options'" },
1036         { 0x46, "type='prev'" },
1037         { 0x47, "type='reset'" },
1038         { 0x48, "type='text'" },
1039         { 0x49, "type='vnd.'" },
1040         { 0x4A, "href=" },
1041         { 0x4B, "href='http://'" },
1042         { 0x4C, "href='https://'" },
1043         { 0x4D, "value=" },
1044         { 0x4E, "vspace=" },
1045         { 0x4F, "width=" },
1046         { 0x50, "xml:lang=" },
1047         /* 0x51 */
1048         { 0x52, "align=" },
1049         { 0x53, "columns=" },
1050         { 0x54, "class=" },
1051         { 0x55, "id=" },
1052         { 0x56, "forua='false'" },
1053         { 0x57, "forua='true'" },
1054         { 0x58, "src='http://'" },
1055         { 0x59, "src='https://'" },
1056         { 0x5A, "http-equiv=" },
1057         { 0x5B, "http-equiv='Content-Type'" },
1058         { 0x5C, "content='application/vnd.wap.wmlc;charset='" },
1059         { 0x5D, "http-equiv='Expires'" },
1060         { 0x5E, "accesskey=" },
1061         { 0x5F, "enctype=" },
1062         { 0x60, "enctype='application/x-www-form-urlencoded'" },
1063         { 0x61, "enctype='multipart/form-data'" },
1064         { 0x62, "xml:space='preserve'" },
1065         { 0x63, "xml:space='default'" },
1066         { 0x64, "cache-control='no-cache'" },
1067
1068         { 0x00, NULL }
1069 };
1070
1071 /*****    Attribute Value tokens   *****/
1072 /* Same as in WML 1.1 */
1073
1074 /***** Token code page aggregation *****/
1075 static const value_valuestring wbxml_wmlc13_global[] = {
1076         { 0, wbxml_wmlc10_global_cp0 }, /* Same as WML 1.0 */
1077         { 0, NULL }
1078 };
1079
1080 static const value_valuestring wbxml_wmlc13_tags[] = {
1081         { 0, wbxml_wmlc12_tags_cp0 },
1082         { 0, NULL }
1083 };
1084
1085 static const value_valuestring wbxml_wmlc13_attrStart[] = {
1086         { 0, wbxml_wmlc13_attrStart_cp0 },
1087         { 0, NULL }
1088 };
1089
1090 static const value_valuestring wbxml_wmlc13_attrValue[] = {
1091         { 0, wbxml_wmlc11_attrValue_cp0 }, /* Same as WML 1.1 */
1092         { 0, NULL }
1093 };
1094
1095 static const wbxml_decoding decode_wmlc_13 = {
1096     "Wireless Markup Language 1.3",
1097     "WML 1.3",
1098     { ext_t_0_wml_10, ext_t_1_wml_10, ext_t_2_wml_10 },
1099     wbxml_wmlc13_global,
1100     wbxml_wmlc13_tags,
1101     wbxml_wmlc13_attrStart,
1102     wbxml_wmlc13_attrValue
1103 };
1104
1105
1106
1107
1108
1109 /* SI 1.0
1110  * 
1111  * Service Indication
1112  ***************************************/
1113
1114 /*****   Global extension tokens   *****/
1115
1116 /*****         Tag tokens          *****/
1117 static const value_string wbxml_sic10_tags_cp0[] = {
1118         /* 0x00 -- 0x04 GLOBAL */
1119         { 0x05, "si" },
1120         { 0x06, "indication" },
1121         { 0x07, "info" },
1122         { 0x08, "item" },
1123
1124         { 0x00, NULL }
1125 };
1126
1127 /*****    Attribute Start tokens   *****/
1128 static const value_string wbxml_sic10_attrStart_cp0[] = {
1129         /* 0x00 -- 0x04 GLOBAL */
1130         { 0x05, "action='signal-none'" },
1131         { 0x06, "action='signal-low'" },
1132         { 0x07, "action='signal-medium'" },
1133         { 0x08, "action='signal-high'" },
1134         { 0x09, "action='delete'" },
1135         { 0x0a, "created=" },
1136         { 0x0b, "href=" },
1137         { 0x0c, "href='http://'" },
1138         { 0x0d, "href='http://www.'" },
1139         { 0x0e, "href='https://'" },
1140         { 0x0f, "href='https://www.'" },
1141         { 0x10, "si-expires=" },
1142         { 0x11, "si-id=" },
1143         { 0x12, "class=" },
1144
1145         { 0x00, NULL }
1146 };
1147
1148 /*****    Attribute Value tokens   *****/
1149 static const value_string wbxml_sic10_attrValue_cp0[] = {
1150         /* 0x80 -- 0x84 GLOBAL */
1151         { 0x85, "'.com/'" },
1152         { 0x86, "'.edu/'" },
1153         { 0x87, "'.net/'" },
1154         { 0x88, "'.org/'" },
1155
1156         { 0x00, NULL }
1157 };
1158
1159 /***** Token code page aggregation *****/
1160 static const value_valuestring wbxml_sic10_tags[] = {
1161         { 0, wbxml_sic10_tags_cp0 },
1162         { 0, NULL }
1163 };
1164
1165 static const value_valuestring wbxml_sic10_attrStart[] = {
1166         { 0, wbxml_sic10_attrStart_cp0 },
1167         { 0, NULL }
1168 };
1169
1170 static const value_valuestring wbxml_sic10_attrValue[] = {
1171         { 0, wbxml_sic10_attrValue_cp0 },
1172         { 0, NULL }
1173 };
1174
1175 static const wbxml_decoding decode_sic_10 = {
1176     "Service Indication 1.0",
1177     "SI 1.0",
1178     { NULL, NULL, NULL },
1179     NULL,
1180     wbxml_sic10_tags,
1181     wbxml_sic10_attrStart,
1182     wbxml_sic10_attrValue
1183 };
1184
1185
1186
1187
1188
1189 /* SL 1.0
1190  * 
1191  * Service Loading
1192  ***************************************/
1193
1194 /*****   Global extension tokens   *****/
1195
1196 /*****         Tag tokens          *****/
1197 static const value_string wbxml_slc10_tags_cp0[] = {
1198         /* 0x00 -- 0x04 GLOBAL */
1199         { 0x05, "sl" },
1200
1201         { 0x00, NULL }
1202 };
1203
1204 /*****    Attribute Start tokens   *****/
1205 static const value_string wbxml_slc10_attrStart_cp0[] = {
1206         /* 0x00 -- 0x04 GLOBAL */
1207         { 0x05, "action='execute-low'" },
1208         { 0x06, "action='execute-high'" },
1209         { 0x07, "action='cache'" },
1210         { 0x08, "href=" },
1211         { 0x09, "href='http://'" },
1212         { 0x0a, "href='http://www.'" },
1213         { 0x0b, "href='https://'" },
1214         { 0x0c, "href='https://www.'" },
1215
1216         { 0x00, NULL }
1217 };
1218
1219 /*****    Attribute Value tokens   *****/
1220 /* Same as in SI 1.0 */
1221
1222 /***** Token code page aggregation *****/
1223 static const value_valuestring wbxml_slc10_tags[] = {
1224         { 0, wbxml_slc10_tags_cp0 },
1225         { 0, NULL }
1226 };
1227
1228 static const value_valuestring wbxml_slc10_attrStart[] = {
1229         { 0, wbxml_slc10_attrStart_cp0 },
1230         { 0, NULL }
1231 };
1232
1233 static const value_valuestring wbxml_slc10_attrValue[] = {
1234         { 0, wbxml_sic10_attrValue_cp0 }, /* Same as SI 1.0 */
1235         { 0, NULL }
1236 };
1237
1238 static const wbxml_decoding decode_slc_10 = {
1239     "Service Loading 1.0",
1240     "SL 1.0",
1241     { NULL, NULL, NULL },
1242     NULL,
1243     wbxml_slc10_tags,
1244     wbxml_slc10_attrStart,
1245     wbxml_slc10_attrValue
1246 };
1247
1248
1249
1250
1251
1252 /* CO 1.0
1253  * 
1254  * Cache Operation
1255  ***************************************/
1256
1257 /*****   Global extension tokens   *****/
1258
1259 /*****         Tag tokens          *****/
1260 static const value_string wbxml_coc10_tags_cp0[] = {
1261         /* 0x00 -- 0x04 GLOBAL */
1262         { 0x05, "co" },
1263         { 0x06, "invalidate-object" },
1264         { 0x07, "invalidate-service" },
1265
1266         { 0x00, NULL }
1267 };
1268
1269 /*****    Attribute Start tokens   *****/
1270 static const value_string wbxml_coc10_attrStart_cp0[] = {
1271         /* 0x00 -- 0x04 GLOBAL */
1272         { 0x05, "uri=" },
1273         { 0x06, "uri='http://'" },
1274         { 0x07, "uri='http://www.'" },
1275         { 0x08, "uri='https://'" },
1276         { 0x09, "uri='https://www.'" },
1277
1278         { 0x00, NULL }
1279 };
1280
1281 /*****    Attribute Value tokens   *****/
1282 /* Same as in SI 1.0 */
1283
1284 /***** Token code page aggregation *****/
1285 static const value_valuestring wbxml_coc10_tags[] = {
1286         { 0, wbxml_coc10_tags_cp0 },
1287         { 0, NULL }
1288 };
1289
1290 static const value_valuestring wbxml_coc10_attrStart[] = {
1291         { 0, wbxml_coc10_attrStart_cp0 },
1292         { 0, NULL }
1293 };
1294
1295 static const value_valuestring wbxml_coc10_attrValue[] = {
1296         { 0, wbxml_sic10_attrValue_cp0 }, /* Same as SI 1.0 */
1297         { 0, NULL }
1298 };
1299
1300 static const wbxml_decoding decode_coc_10 = {
1301     "Cache Operation 1.0",
1302     "CO 1.0",
1303     { NULL, NULL, NULL },
1304     NULL,
1305     wbxml_coc10_tags,
1306     wbxml_coc10_attrStart,
1307     wbxml_coc10_attrValue
1308 };
1309
1310
1311
1312
1313
1314 /* PROV 1.0
1315  *
1316  * Client Provisioning
1317  ***************************************/
1318
1319 /*****   Global extension tokens   *****/
1320
1321 /*****         Tag tokens          *****/
1322 static const value_string wbxml_provc10_tags_cp0[] = {
1323         /* 0x00 -- 0x04 GLOBAL */
1324         { 0x05, "wap-provisioningdoc" },
1325         { 0x06, "characteristic" },
1326         { 0x07, "parm" },
1327
1328         { 0x00, NULL }
1329 };
1330 static const value_string wbxml_provc10_tags_cp1[] = {
1331         /* 0x00 -- 0x04 GLOBAL */
1332         /* 0x05 */
1333         { 0x06, "characteristic" },
1334         { 0x07, "parm" },
1335
1336         { 0x00, NULL }
1337 };
1338
1339 /*****    Attribute Start tokens   *****/
1340 static const value_string wbxml_provc10_attrStart_cp0[] = {
1341         /* 0x00 -- 0x04 GLOBAL */
1342         { 0x05, "name=" },
1343         { 0x06, "value=" },
1344         { 0x07, "name='NAME'" },
1345         { 0x08, "name='NAP-ADDRESS'" },
1346         { 0x09, "name='NAP-ADDRTYPE'" },
1347         { 0x0A, "name='CALLTYPE'" },
1348         { 0x0B, "name='VALIDUNTIL'" },
1349         { 0x0C, "name='AUTHTYPE'" },
1350         { 0x0D, "name='AUTHNAME'" },
1351         { 0x0E, "name='AUTHSECRET'" },
1352         { 0x0F, "name='LINGER'" },
1353         { 0x10, "name='BEARER'" },
1354         { 0x11, "name='NAPID'" },
1355         { 0x12, "name='COUNTRY'" },
1356         { 0x13, "name='NETWORK'" },
1357         { 0x14, "name='INTERNET'" },
1358         { 0x15, "name='PROXY-ID'" },
1359         { 0x16, "name='PROXY-PROVIDER-ID'" },
1360         { 0x17, "name='DOMAIN'" },
1361         { 0x18, "name='PROVURL'" },
1362         { 0x19, "name='PXAUTH-TYPE'" },
1363         { 0x1A, "name='PXAUTH-ID'" },
1364         { 0x1B, "name='PXAUTH-PW'" },
1365         { 0x1C, "name='STARTPAGE'" },
1366         { 0x1D, "name='BASAUTH-ID'" },
1367         { 0x1E, "name='BASAUTH-PW'" },
1368         { 0x1F, "name='PUSHENABLED'" },
1369         { 0x20, "name='PXADDR'" },
1370         { 0x21, "name='PXADDRTYPE'" },
1371         { 0x22, "name='TO-NAPID'" },
1372         { 0x23, "name='PORTNBR'" },
1373         { 0x24, "name='SERVICE'" },
1374         { 0x25, "name='LINKSPEED'" },
1375         { 0x26, "name='DNLINKSPEED'" },
1376         { 0x27, "name='LOCAL-ADDR'" },
1377         { 0x28, "name='LOCAL-ADDRTYPE'" },
1378         { 0x29, "name='CONTEXT-ALLOW'" },
1379         { 0x2A, "name='TRUST'" },
1380         { 0x2B, "name='MASTER'" },
1381         { 0x2C, "name='SID'" },
1382         { 0x2D, "name='SOC'" },
1383         { 0x2E, "name='WSP-VERSION'" },
1384         { 0x2F, "name='PHYSICAL-PROXY-ID'" },
1385         { 0x30, "name='CLIENT-ID'" },
1386         { 0x31, "name='DELIVERY-ERR-SDU'" },
1387         { 0x32, "name='DELIVERY-ORDER'" },
1388         { 0x33, "name='TRAFFIC-CLASS'" },
1389         { 0x34, "name='MAX-SDU-SIZE'" },
1390         { 0x35, "name='MAX-BITRATE-UPLINK'" },
1391         { 0x36, "name='MAX-BITRATE-DNLINK'" },
1392         { 0x37, "name='RESIDUAL-BER'" },
1393         { 0x38, "name='SDU-ERROR-RATIO'" },
1394         { 0x39, "name='TRAFFIC-HANDL-PRIO'" },
1395         { 0x3A, "name='TRANSFER-DELAY'" },
1396         { 0x3B, "name='GUARANTEED-BITRATE-UPLINK'" },
1397         { 0x3C, "name='GUARANTEED-BITRATE-DNLINK'" },
1398         { 0x3D, "name='PXADDR-FQDN'" },
1399         { 0x3E, "name='PROXY-PW'" },
1400         { 0x3F, "name='PPGAUTH-TYPE'" },
1401         /* 0x40 -- 0x44 GLOBAL */
1402         { 0x45, "version=" },
1403         { 0x46, "version='1.0'" },
1404         { 0x47, "name='PULLENABLED'" },
1405         { 0x48, "name='DNS-ADDR'" },
1406         { 0x49, "name='MAX-NUM-RETRY'" },
1407         { 0x4A, "name='FIRST-RETRY-TIMEOUT'" },
1408         { 0x4B, "name='REREG-THRESHOLD'" },
1409         { 0x4C, "name='T-BIT'" },
1410         /* 0x4D */
1411         { 0x4E, "name='AUTH-ENTITY'" },
1412         { 0x4F, "name='SPI'" },
1413         { 0x50, "type=" },
1414         { 0x51, "type='PXLOGICAL'" },
1415         { 0x52, "type='PXPHYSICAL'" },
1416         { 0x53, "type='PORT'" },
1417         { 0x54, "type='VALIDITY'" },
1418         { 0x55, "type='NAPDEF'" },
1419         { 0x56, "type='BOOTSTRAP'" },
1420         { 0x57, "type='VENDORCONFIG'" },
1421         { 0x58, "type='CLIENTIDENTITY'" },
1422         { 0x59, "type='PXAUTHINFO'" },
1423         { 0x5A, "type='NAPAUTHINFO'" },
1424         { 0x5B, "type='ACCESS'" },
1425
1426         { 0x00, NULL }
1427 };
1428 static const value_string wbxml_provc10_attrStart_cp1[] = {
1429         /* 0x00 -- 0x04 GLOBAL */
1430         /* 0x05 -- 0x06 */
1431         { 0x07, "name='NAME'" },
1432         /* 0x08 -- 0x13 */
1433         { 0x14, "name='INTERNET'" },
1434         /* 0x15 -- 0x1B */
1435         { 0x1C, "name='STARTPAGE'" },
1436         /* 0x1D -- 0x21 */
1437         { 0x22, "name='TO-NAPID'" },
1438         { 0x23, "name='PORTNBR'" },
1439         { 0x24, "name='SERVICE'" },
1440         /* 0x25 -- 0x2D */
1441         { 0x2E, "name='AACCEPT'" },
1442         { 0x2F, "name='AAUTHDATA'" },
1443         { 0x30, "name='AAUTHLEVEL'" },
1444         { 0x31, "name='AAUTHNAME'" },
1445         { 0x32, "name='AAUTHSECRET'" },
1446         { 0x33, "name='AAUTHTYPE'" },
1447         { 0x34, "name='ADDR'" },
1448         { 0x35, "name='ADDRTYPE'" },
1449         { 0x36, "name='APPID'" },
1450         { 0x37, "name='APROTOCOL'" },
1451         { 0x38, "name='PROVIDER-ID'" },
1452         { 0x39, "name='TO-PROXY'" },
1453         { 0x3A, "name='URI'" },
1454         { 0x3B, "name='RULE'" },
1455         /* 0x3C -- 0x3F */
1456         /* 0x40 -- 0x44 GLOBAL */
1457         /* 0x45 -- 0x4F */
1458         { 0x50, "type=" },
1459         /* 0x51 -- 0x52 */
1460         { 0x53, "type='PORT'" },
1461         /* 0x54 */
1462         { 0x55, "type='APPLICATION'" },
1463         { 0x56, "type='APPADDR'" },
1464         { 0x57, "type='APPAUTH'" },
1465         { 0x58, "type='CLIENTIDENTITY'" },
1466         { 0x59, "type='RESOURCE'" },
1467         /* 0x5A -- 0x7F */
1468
1469         { 0x00, NULL }
1470 };
1471
1472 /*****    Attribute Start tokens   *****/
1473 static const value_string wbxml_provc10_attrValue_cp0[] = {
1474         /* 0x80 -- 0x84 GLOBAL */
1475         { 0x85, "'IPV4'" },
1476         { 0x86, "'IPV6'" },
1477         { 0x87, "'E164'" },
1478         { 0x88, "'ALPHA'" },
1479         { 0x89, "'APN'" },
1480         { 0x8A, "'SCODE'" },
1481         { 0x8B, "'TETRA-ITSI'" },
1482         { 0x8C, "'MAN'" },
1483         /* 0x8D -- 0x8F */
1484         { 0x90, "'ANALOG-MODEM'" },
1485         { 0x91, "'V.120'" },
1486         { 0x92, "'V.110'" },
1487         { 0x93, "'X.31'" },
1488         { 0x94, "'BIT-TRANSPARENT'" },
1489         { 0x95, "'DIRECT-ASYNCHRONOUS-DATA-SERVICE'" },
1490         /* 0x96 -- 0x99 */
1491         { 0x9A, "'PAP'" },
1492         { 0x9B, "'CHAP'" },
1493         { 0x9C, "'HTTP-BASIC'" },
1494         { 0x9D, "'HTTP-DIGEST'" },
1495         { 0x9E, "'WTLS-SS'" },
1496         { 0x9F, "'MD5'" },
1497         /* 0xA0 -- 0xA1 */
1498         { 0xA2, "'GSM-USSD'" },
1499         { 0xA3, "'GSM-SMS'" },
1500         { 0xA4, "'ANSI-136-GUTS'" },
1501         { 0xA5, "'IS-95-CDMA-SMS'" },
1502         { 0xA6, "'IS-95-CDMA-CSD'" },
1503         { 0xA7, "'IS-95-CDMA-PACKET'" },
1504         { 0xA8, "'ANSI-136-CSD'" },
1505         { 0xA9, "'ANSI-136-GPRS'" },
1506         { 0xAA, "'GSM-CSD'" },
1507         { 0xAB, "'GSM-GPRS'" },
1508         { 0xAC, "'AMPS-CDPD'" },
1509         { 0xAD, "'PDC-CSD'" },
1510         { 0xAE, "'PDC-PACKET'" },
1511         { 0xAF, "'IDEN-SMS'" },
1512         { 0xB0, "'IDEN-CSD'" },
1513         { 0xB1, "'IDEN-PACKET'" },
1514         { 0xB2, "'FLEX/REFLEX'" },
1515         { 0xB3, "'PHS-SMS'" },
1516         { 0xB4, "'PHS-CSD'" },
1517         { 0xB5, "'TETRA-SDS'" },
1518         { 0xB6, "'TETRA-PACKET'" },
1519         { 0xB7, "'ANSI-136-GHOST'" },
1520         { 0xB8, "'MOBITEX-MPAK'" },
1521         { 0xB9, "'CDMA2000-IX-SIMPLE-IP'" },
1522         { 0xBA, "'CDMA2000-IX-MOBILE-IP'" },
1523         /* 0xBB -- 0xBF */
1524         /* 0xC0 -- 0xC4 GLOBAL */
1525         { 0xC5, "'AUTOBAUDING'" },
1526         /* 0xC6 -- 0xC9 */
1527         { 0xCA, "'CL-WSP'" },
1528         { 0xCB, "'CO-WSP'" },
1529         { 0xCC, "'CL-SEC-WSP'" },
1530         { 0xCD, "'CO-SEC-WSP'" },
1531         { 0xCE, "'CL-SEC-WTA'" },
1532         { 0xCF, "'CO-SEC-WTA'" },
1533         { 0xD0, "'OTA-HTTP-TO'" },
1534         { 0xD1, "'OTA-HTTP-TLS-TO'" },
1535         { 0xD2, "'OTA-HTTP-PO'" },
1536         { 0xD3, "'OTA-HTTP-TLS-PO'" },
1537         /* 0xD4 -- 0xFF */
1538
1539         { 0x00, NULL }
1540 };
1541 static const value_string wbxml_provc10_attrValue_cp1[] = {
1542         /* 0x80 -- 0x84 GLOBAL */
1543         /* 0x85 */
1544         { 0x86, "'IPV6'" },
1545         { 0x87, "'E164'" },
1546         { 0x88, "'ALPHA'" },
1547         { 0x8D, "'APPSRV'" },
1548         { 0x8E, "'OBEX'" },
1549         /* 0x8F */
1550
1551         /* XXX - Errors that require a fix in the OMA/WAP Client Provisioning specs:
1552         { 0xXXX, "','" },
1553         { 0xXXX, "'HTTP-'" },
1554         { 0xXXX, "'BASIC'" },
1555         { 0xXXX, "'DIGEST'" },
1556         */
1557
1558         { 0xE0, "'AAA'" },
1559         { 0xE1, "'HA'" },
1560
1561         { 0x00, NULL }
1562 };
1563
1564 /***** Token code page aggregation *****/
1565 static const value_valuestring wbxml_provc10_tags[] = {
1566         { 0, wbxml_provc10_tags_cp0 },
1567         { 1, wbxml_provc10_tags_cp1 },
1568         { 0, NULL }
1569 };
1570
1571 static const value_valuestring wbxml_provc10_attrStart[] = {
1572         { 0, wbxml_provc10_attrStart_cp0 },
1573         { 1, wbxml_provc10_attrStart_cp1 },
1574         { 0, NULL }
1575 };
1576
1577 static const value_valuestring wbxml_provc10_attrValue[] = {
1578         { 0, wbxml_provc10_attrValue_cp0 },
1579         { 1, wbxml_provc10_attrValue_cp1 },
1580         { 0, NULL }
1581 };
1582
1583 static const wbxml_decoding decode_provc_10 = {
1584     "WAP Client Provisioning Document 1.0",
1585     "WAP ProvisioningDoc 1.0",
1586     { NULL, NULL, NULL },
1587     NULL,
1588     wbxml_provc10_tags,
1589     wbxml_provc10_attrStart,
1590     wbxml_provc10_attrValue
1591 };
1592
1593
1594
1595
1596
1597 /* EMN 1.0
1598  * 
1599  * Email Notification
1600  ***************************************/
1601
1602 /*****   Global extension tokens   *****/
1603
1604 /*****         Tag tokens          *****/
1605 static const value_string wbxml_emnc10_tags_cp0[] = {
1606         /* 0x00 -- 0x04 GLOBAL */
1607         { 0x05, "emn" },
1608
1609         { 0x00, NULL }
1610 };
1611
1612 /*****    Attribute Start tokens   *****/
1613 static const value_string wbxml_emnc10_attrStart_cp0[] = {
1614         /* 0x00 -- 0x04 GLOBAL */
1615         { 0x05, "timestamp=" },
1616         { 0x06, "mailbox=" },
1617         { 0x07, "mailbox='mailat:'" },
1618         { 0x08, "mailbox='pop://'" },
1619         { 0x09, "mailbox='imap://'" },
1620         { 0x0a, "mailbox='http://'" },
1621         { 0x0b, "mailbox='http://www.'" },
1622         { 0x0c, "mailbox='https://'" },
1623         { 0x0D, "mailbox='https://www.'" },
1624
1625         { 0x00, NULL }
1626 };
1627
1628 /*****    Attribute Value tokens   *****/
1629 /* Same as in SI 1.0 */
1630
1631 /***** Token code page aggregation *****/
1632 static const value_valuestring wbxml_emnc10_tags[] = {
1633         { 0, wbxml_emnc10_tags_cp0 },
1634         { 0, NULL }
1635 };
1636
1637 static const value_valuestring wbxml_emnc10_attrStart[] = {
1638         { 0, wbxml_emnc10_attrStart_cp0 },
1639         { 0, NULL }
1640 };
1641
1642 static const value_valuestring wbxml_emnc10_attrValue[] = {
1643         { 0, wbxml_sic10_attrValue_cp0 }, /* Same as SI 1.0 */
1644         { 0, NULL }
1645 };
1646
1647 static const wbxml_decoding decode_emnc_10 = {
1648     "E-Mail Notification 1.0",
1649     "EMN 1.0",
1650     { NULL, NULL, NULL },
1651     NULL,
1652     wbxml_emnc10_tags,
1653     wbxml_emnc10_attrStart,
1654     wbxml_emnc10_attrValue
1655 };
1656
1657
1658
1659
1660
1661 /* SyncML 1.0
1662  * 
1663  * SyncML Representation Protocol
1664  ***************************************/
1665
1666 /*****   Global extension tokens   *****/
1667
1668 /*****         Tag tokens          *****/
1669 static const value_string wbxml_syncmlc10_tags_cp0[] = { /* SyncML 1.0 */
1670         /* 0x00 -- 0x04 GLOBAL */
1671         { 0x05, "Add" },
1672         { 0x06, "Alert" },
1673         { 0x07, "Archive" },
1674         { 0x08, "Atomic" },
1675         { 0x09, "Chal" },
1676         { 0x0A, "Cmd" },
1677         { 0x0B, "CmdID" },
1678         { 0x0C, "CmdRef" },
1679         { 0x0D, "Copy" },
1680         { 0x0E, "Cred" },
1681         { 0x0F, "Data" },
1682         { 0x10, "Delete" },
1683         { 0x11, "Exec" },
1684         { 0x12, "Final" },
1685         { 0x13, "Get" },
1686         { 0x14, "Item" },
1687         { 0x15, "Lang" },
1688         { 0x16, "LocName" },
1689         { 0x17, "LocURI" },
1690         { 0x18, "Map" },
1691         { 0x19, "MapItem" },
1692         { 0x1A, "Meta" },
1693         { 0x1B, "MsgID" },
1694         { 0x1C, "MsgRef" },
1695         { 0x1D, "NoResp" },
1696         { 0x1E, "NoResults" },
1697         { 0x1F, "Put" },
1698         { 0x20, "Replace" },
1699         { 0x21, "RespURI" },
1700         { 0x22, "Results" },
1701         { 0x23, "Search" },
1702         { 0x24, "Sequence" },
1703         { 0x25, "SessionID" },
1704         { 0x26, "SftDel" },
1705         { 0x27, "Source" },
1706         { 0x28, "SourceRef" },
1707         { 0x29, "Status" },
1708         { 0x2A, "Sync" },
1709         { 0x2B, "SyncBody" },
1710         { 0x2C, "SyncHdr" },
1711         { 0x2D, "SyncML" },
1712         { 0x2E, "Target" },
1713         { 0x2F, "TargetRef" },
1714         /* 0x30 - Reserved */
1715         { 0x31, "VerDTD" },
1716         { 0x32, "VerProto" },
1717
1718         { 0x00, NULL }
1719 };
1720
1721 static const value_string wbxml_syncmlc10_tags_cp1[] = { /* MetInf 1.0 */
1722         /* 0x00 -- 0x04 GLOBAL */
1723         { 0x05, "Anchor" },
1724         { 0x06, "EMI" },
1725         { 0x07, "Format" },
1726         { 0x08, "FreeID" },
1727         { 0x09, "FreeMem" },
1728         { 0x0A, "Last" },
1729         { 0x0B, "Mark" },
1730         { 0x0C, "MaxMsgSize" },
1731         { 0x0D, "Mem" },
1732         { 0x0E, "MetInf" },
1733         { 0x0F, "Next" },
1734         { 0x10, "NextNonce" },
1735         { 0x11, "SharedMem" },
1736         { 0x12, "Size" },
1737         { 0x13, "Type" },
1738         { 0x14, "Version" },
1739
1740         { 0x00, NULL }
1741 };
1742
1743 /*****    Attribute Start tokens   *****/
1744
1745 /*****    Attribute Value tokens   *****/
1746
1747 /***** Token code page aggregation *****/
1748 static const value_valuestring wbxml_syncmlc10_tags[] = {
1749         { 0, wbxml_syncmlc10_tags_cp0 }, /* -//SYNCML//DTD SyncML 1.0//EN */
1750         { 1, wbxml_syncmlc10_tags_cp1 }, /* -//SYNCML//DTD MetInf 1.0//EN */
1751         { 0, NULL }
1752 };
1753
1754 static const wbxml_decoding decode_syncmlc_10 = {
1755     "SyncML Representation Protocol 1.0",
1756     "SyncML 1.0",
1757     { NULL, NULL, NULL },
1758     NULL,
1759     wbxml_syncmlc10_tags,
1760     NULL,
1761     NULL
1762 };
1763
1764
1765
1766
1767
1768 /* SyncML 1.1
1769  * 
1770  * SyncML Representation Protocol
1771  ***************************************/
1772
1773 /*****   Global extension tokens   *****/
1774
1775 /*****         Tag tokens          *****/
1776 static const value_string wbxml_syncmlc11_tags_cp0[] = { /* SyncML 1.1 */
1777         /* 0x00 -- 0x04 GLOBAL */
1778         { 0x05, "Add" },
1779         { 0x06, "Alert" },
1780         { 0x07, "Archive" },
1781         { 0x08, "Atomic" },
1782         { 0x09, "Chal" },
1783         { 0x0a, "Cmd" },
1784         { 0x0b, "CmdID" },
1785         { 0x0c, "CmdRef" },
1786         { 0x0d, "Copy" },
1787         { 0x0e, "Cred" },
1788         { 0x0f, "Data" },
1789         { 0x10, "Delete" },
1790         { 0x11, "Exec" },
1791         { 0x12, "Final" },
1792         { 0x13, "Get" },
1793         { 0x14, "Item" },
1794         { 0x15, "Lang" },
1795         { 0x16, "LocName" },
1796         { 0x17, "LocURI" },
1797         { 0x18, "Map" },
1798         { 0x19, "MapItem" },
1799         { 0x1a, "Meta" },
1800         { 0x1b, "MsgID" },
1801         { 0x1c, "MsgRef" },
1802         { 0x1d, "NoResp" },
1803         { 0x1e, "NoResults" },
1804         { 0x1f, "Put" },
1805         { 0x20, "Replace" },
1806         { 0x21, "RespURI" },
1807         { 0x22, "Results" },
1808         { 0x23, "Search" },
1809         { 0x24, "Sequence" },
1810         { 0x25, "SessionID" },
1811         { 0x26, "SftDel" },
1812         { 0x27, "Source" },
1813         { 0x28, "SourceRef" },
1814         { 0x29, "Status" },
1815         { 0x2a, "Sync" },
1816         { 0x2b, "SyncBody" },
1817         { 0x2c, "SyncHdr" },
1818         { 0x2d, "SyncML" },
1819         { 0x2e, "Target" },
1820         { 0x2f, "TargetRef" },
1821         /* 0x30 - Reserved */
1822         { 0x31, "VerDTD" },
1823         { 0x32, "VerProto" },
1824         { 0x33, "NumberOfChanges" },
1825         { 0x34, "MoreData" },
1826
1827         { 0x00, NULL }
1828 };
1829
1830 static const value_string wbxml_syncmlc11_tags_cp1[] = { /* MetInf 1.1 */
1831         /* 0x00 -- 0x04 GLOBAL */
1832         { 0x05, "Anchor" },
1833         { 0x06, "EMI" },
1834         { 0x07, "Format" },
1835         { 0x08, "FreeID" },
1836         { 0x09, "FreeMem" },
1837         { 0x0A, "Last" },
1838         { 0x0B, "Mark" },
1839         { 0x0C, "MaxMsgSize" },
1840         { 0x0D, "Mem" },
1841         { 0x0E, "MetInf" },
1842         { 0x0F, "Next" },
1843         { 0x10, "NextNonce" },
1844         { 0x11, "SharedMem" },
1845         { 0x12, "Size" },
1846         { 0x13, "Type" },
1847         { 0x14, "Version" },
1848         { 0x15, "MaxObjSize" },
1849
1850         { 0x00, NULL }
1851 };
1852
1853 /*****    Attribute Start tokens   *****/
1854
1855 /*****    Attribute Value tokens   *****/
1856
1857 /***** Token code page aggregation *****/
1858 static const value_valuestring wbxml_syncmlc11_tags[] = {
1859         { 0, wbxml_syncmlc11_tags_cp0 }, /* -//SYNCML//DTD SyncML 1.1//EN */
1860         { 1, wbxml_syncmlc11_tags_cp1 }, /* -//SYNCML//DTD MetInf 1.1//EN */
1861         { 0, NULL }
1862 };
1863
1864 static const wbxml_decoding decode_syncmlc_11 = {
1865     "SyncML Representation Protocol 1.1",
1866     "SyncML 1.1",
1867     { NULL, NULL, NULL },
1868     NULL,
1869     wbxml_syncmlc11_tags,
1870     NULL,
1871     NULL
1872 };
1873
1874
1875
1876
1877
1878 /* CHANNEL 1.0
1879  * 
1880  * WTA Channel
1881  ***************************************/
1882
1883 /*****   Global extension tokens   *****/
1884
1885 /*****         Tag tokens          *****/
1886 static const value_string wbxml_channelc10_tags_cp0[] = {
1887         /* 0x00 -- 0x04 GLOBAL */
1888         { 0x05, "channel" },
1889         { 0x06, "title" },
1890         { 0x07, "abstract" },
1891         { 0x08, "resource" },
1892
1893         { 0x00, NULL }
1894 };
1895
1896 /*****    Attribute Start tokens   *****/
1897 static const value_string wbxml_channelc10_attrStart_cp0[] = {
1898         /* 0x00 -- 0x04 GLOBAL */
1899         { 0x05, "maxspace=" },
1900         { 0x06, "base=" },
1901         { 0x07, "href=" },
1902         { 0x08, "href='http://'" },
1903         { 0x09, "href='https://'" },
1904         { 0x0A, "lastmod=" },
1905         { 0x0B, "etag=" },
1906         { 0x0C, "md5=" },
1907         { 0x0D, "success=" },
1908         { 0x0E, "success='http://'" },
1909         { 0x0F, "success='https://'" },
1910         { 0x10, "failure=" },
1911         { 0x11, "failure='http://'" },
1912         { 0x12, "failure='https://'" },
1913         { 0x13, "EventId=" },
1914
1915         { 0x00, NULL }
1916 };
1917
1918 /*****    Attribute Value tokens   *****/
1919
1920 /***** Token code page aggregation *****/
1921 static const value_valuestring wbxml_channelc10_tags[] = {
1922         { 0, wbxml_channelc10_tags_cp0 },
1923         { 0, NULL }
1924 };
1925
1926 static const value_valuestring wbxml_channelc10_attrStart[] = {
1927         { 0, wbxml_channelc10_attrStart_cp0 },
1928         { 0, NULL }
1929 };
1930
1931 static const wbxml_decoding decode_channelc_10 = {
1932     "Wireless Telephony Application (WTA) Channel 1.0",
1933     "CHANNEL 1.0",
1934     { NULL, NULL, NULL },
1935     NULL,
1936     wbxml_channelc10_tags,
1937     wbxml_channelc10_attrStart,
1938     NULL
1939 };
1940
1941
1942
1943
1944
1945 /* application/x-wap-prov.browser-settings
1946  * application/x-wap-prov.browser-bookmarks
1947  * 
1948  * Nokia OTA Provisioning document format
1949  ***************************************/
1950
1951 /*****   Global extension tokens   *****/
1952
1953 /*****         Tag tokens          *****/
1954 static const value_string wbxml_nokiaprovc70_tags_cp0[] = {
1955         /* 0x00 -- 0x04 GLOBAL */
1956         { 0x05, "CHARACTERISTIC-LIST" },
1957         { 0x06, "CHARACTERISTIC" },
1958         { 0x07, "PARM" },
1959
1960         { 0x00, NULL }
1961 };
1962
1963 /*****    Attribute Start tokens   *****/
1964 static const value_string wbxml_nokiaprovc70_attrStart_cp0[] = {
1965         /* 0x00 -- 0x04 GLOBAL */
1966         { 0x06, "TYPE='ADDRESS'" },
1967         { 0x07, "TYPE='URL'" },
1968         { 0x08, "TYPE='NAME'" },
1969         { 0x10, "NAME=" },
1970         { 0x11, "VALUE=" },
1971         { 0x12, "NAME='BEARER'" },
1972         { 0x13, "NAME='PROXY'" },
1973         { 0x14, "NAME='PORT'" },
1974         { 0x15, "NAME='NAME'" },
1975         { 0x16, "NAME='PROXY_TYPE'" },
1976         { 0x17, "NAME='URL'" },
1977         { 0x18, "NAME='PROXY_AUTHNAME'" },
1978         { 0x19, "NAME='PROXY_AUTHSECRET'" },
1979         { 0x1A, "NAME='SMS_SMSC_ADDRESS'" },
1980         { 0x1B, "NAME='USSD_SERVICE_CODE'" },
1981         { 0x1C, "NAME='GPRS_ACCESSPOINTNAME'" },
1982         { 0x1D, "NAME='PPP_LOGINTYPE'" },
1983         { 0x1E, "NAME='PROXY_LOGINTYPE'" },
1984         { 0x21, "NAME='CSD_DIALSTRING'" },
1985         { 0x22, "NAME='PPP_AUTHTYPE'" },
1986         { 0x23, "NAME='PPP_AUTHNAME'" },
1987         { 0x24, "NAME='PPP_AUTHSECRET'" },
1988         { 0x28, "NAME='CSD_CALLTYPE'" },
1989         { 0x29, "NAME='CSD_CALLSPEED'" },
1990         { 0x45, "VALUE='GSM/CSD'" },
1991         { 0x46, "VALUE='GSM/SMS'" },
1992         { 0x47, "VALUE='GSM/USSD'" },
1993         { 0x48, "VALUE='IS-136/CSD'" },
1994         { 0x49, "VALUE='GPRS'" },
1995         { 0x60, "VALUE='9200'" },
1996         { 0x61, "VALUE='9201'" },
1997         { 0x62, "VALUE='9202'" },
1998         { 0x63, "VALUE='9203'" },
1999         { 0x64, "VALUE='AUTOMATIC'" },
2000         { 0x65, "VALUE='MANUAL'" },
2001         { 0x6A, "VALUE='AUTO'" },
2002         { 0x6B, "VALUE='9600'" },
2003         { 0x6C, "VALUE='14400'" },
2004         { 0x6D, "VALUE='19200'" },
2005         { 0x6E, "VALUE='28800'" },
2006         { 0x6F, "VALUE='38400'" },
2007         { 0x70, "VALUE='PAP'" },
2008         { 0x71, "VALUE='CHAP'" },
2009         { 0x72, "VALUE='ANALOGUE'" },
2010         { 0x73, "VALUE='ISDN'" },
2011         { 0x74, "VALUE='43200'" },
2012         { 0x75, "VALUE='57600'" },
2013         { 0x76, "VALUE='MSISDN_NO'" },
2014         { 0x77, "VALUE='IPV4'" },
2015         { 0x78, "VALUE='MS_CHAP'" },
2016         { 0x7C, "TYPE='MMSURL'" },
2017         { 0x7D, "TYPE='ID'" },
2018         { 0x7E, "NAME='ISP_NAME'" },
2019         { 0x7F, "TYPE='BOOKMARK'" },
2020
2021         { 0x00, NULL }
2022 };
2023
2024 /*****    Attribute Value tokens   *****/
2025
2026 /***** Token code page aggregation *****/
2027 static const value_valuestring wbxml_nokiaprovc70_tags[] = {
2028         { 0, wbxml_nokiaprovc70_tags_cp0 },
2029         { 0, NULL }
2030 };
2031
2032 static const value_valuestring wbxml_nokiaprovc70_attrStart[] = {
2033         { 0, wbxml_nokiaprovc70_attrStart_cp0 },
2034         { 0, NULL }
2035 };
2036
2037 static const wbxml_decoding decode_nokiaprovc_70 = {
2038     "Nokia Client Provisioning 7.0",
2039     "Nokia Client Provisioning 7.0",
2040     { NULL, NULL, NULL },
2041     NULL,
2042     wbxml_nokiaprovc70_tags,
2043     wbxml_nokiaprovc70_attrStart,
2044     NULL
2045 };
2046
2047
2048
2049
2050
2051 /* WV-CSP 1.0
2052  * 
2053  * Wireless Village Client Server Protocol
2054  ***************************************/
2055
2056 /*****   Global extension tokens   *****/
2057
2058 /*****         Tag tokens          *****/
2059 /* Common code page (0x00) */
2060 static const value_string wbxml_wv_csp_10_tags_cp0[] = {
2061         /* 0x00 -- 0x04 GLOBAL */
2062         { 0x05, "Acceptance" },
2063         { 0x06, "AddList" },
2064         { 0x07, "AddNickList" },
2065         { 0x08, "Attribute" },
2066         { 0x09, "AttributeList" },
2067         { 0x0A, "ClientID" },
2068         { 0x0B, "Code" },
2069         { 0x0C, "ContactList" },
2070         { 0x0D, "ContentData" },
2071         { 0x0E, "ContentEncoding" },
2072         { 0x0F, "ContentSize" },
2073         { 0x10, "ContentType" },
2074         { 0x11, "DateTime" },
2075         { 0x12, "Description" },
2076         { 0x13, "DetailedResult" },
2077         { 0x14, "EntityList" },
2078         { 0x15, "Group" },
2079         { 0x16, "GroupID" },
2080         { 0x17, "GroupList" },
2081         { 0x18, "InUse" },
2082         { 0x19, "Logo" },
2083         { 0x1A, "MessageCount" },
2084         { 0x1B, "MessageID" },
2085         { 0x1C, "MessageURI" },
2086         { 0x1D, "MSISDN" },
2087         { 0x1E, "Name" },
2088         { 0x1F, "NickList" },
2089         { 0x20, "NickName" },
2090         { 0x21, "Poll" },
2091         { 0x22, "Presence" },
2092         { 0x23, "PresenceSubList" },
2093         { 0x24, "PresenceValue" },
2094         { 0x25, "Property" },
2095         { 0x26, "Qualifier" },
2096         { 0x27, "Recipient" },
2097         { 0x28, "RemoveList" },
2098         { 0x29, "RemoveNickList" },
2099         { 0x2A, "Result" },
2100         { 0x2B, "ScreenName" },
2101         { 0x2C, "Sender" },
2102         { 0x2D, "Session" },
2103         { 0x2E, "SessionDescriptor" },
2104         { 0x2F, "SessionID" },
2105         { 0x30, "SessionType" },
2106         { 0x31, "Status" },
2107         { 0x32, "Transaction" },
2108         { 0x33, "TransactionContent" },
2109         { 0x34, "TransactionDescriptor" },
2110         { 0x35, "TransactionID" },
2111         { 0x36, "TransactionMode" },
2112         { 0x37, "URL" },
2113         { 0x38, "URLList" },
2114         { 0x39, "User" },
2115         { 0x3A, "UserID" },
2116         { 0x3B, "UserList" },
2117         { 0x3C, "Validity" },
2118         { 0x3D, "Value" },
2119         { 0x3E, "WV-CSP-Message" },
2120
2121         { 0x00, NULL }
2122 };
2123
2124 /* Access code page (0x01) */
2125 static const value_string wbxml_wv_csp_10_tags_cp1[] = {
2126         /* 0x00 -- 0x04 GLOBAL */
2127         { 0x05, "AllFunctions" },
2128         { 0x06, "AllFunctionsRequest" },
2129         { 0x07, "CancelInvite-Request" },
2130         { 0x08, "CancelInviteUser-Request" },
2131         { 0x09, "Capability" },
2132         { 0x0A, "CapabilityList" },
2133         { 0x0B, "CapabilityRequest" },
2134         { 0x0C, "ClientCapability-Request" },
2135         { 0x0D, "ClientCapability-Response" },
2136         { 0x0E, "DigestBytes" },
2137         { 0x0F, "DigestSchema" },
2138         { 0x10, "Disconnect" },
2139         { 0x11, "Functions" },
2140         { 0x12, "GetSPInfo-Request" },
2141         { 0x13, "GetSPInfo-Response" },
2142         { 0x14, "InviteID" },
2143         { 0x15, "InviteNote" },
2144         { 0x16, "Invite-Request" },
2145         { 0x17, "Invite-Response" },
2146         { 0x18, "InviteType" },
2147         { 0x19, "InviteUser-Request" },
2148         { 0x1A, "InviteUser-Response" },
2149         { 0x1B, "KeepAlive-Request" },
2150         { 0x1C, "KeepAliveTime" },
2151         { 0x1D, "Login-Request" },
2152         { 0x1E, "Login-Response" },
2153         { 0x1F, "Logout-Request" },
2154         { 0x20, "Nonce" },
2155         { 0x21, "Password" },
2156         { 0x22, "Polling-Request" },
2157         { 0x23, "ResponseNote" },
2158         { 0x24, "SearchElement" },
2159         { 0x25, "SearchFindings" },
2160         { 0x26, "SearchID" },
2161         { 0x27, "SearchIndex" },
2162         { 0x28, "SearchLimit" },
2163         { 0x29, "SearchOnlineStatus" },
2164         { 0x2A, "SearchPairList" },
2165         { 0x2B, "Search-Request" },
2166         { 0x2C, "Search-Response" },
2167         { 0x2D, "SearchResult" },
2168         { 0x2E, "Service-Request" },
2169         { 0x2F, "Service-Response" },
2170         { 0x30, "SessionCookie" },
2171         { 0x31, "StopSearch-Request" },
2172         { 0x32, "TimeToLive" },
2173
2174         { 0x00, NULL }
2175 };
2176
2177 /* Service code page (0x02) */
2178 static const value_string wbxml_wv_csp_10_tags_cp2[] = {
2179         /* 0x00 -- 0x04 GLOBAL */
2180         { 0x05, "ADDGM" },
2181         { 0x06, "AttListFunc" },
2182         { 0x07, "BLENT" },
2183         { 0x08, "CAAUT" },
2184         { 0x09, "CAINV" },
2185         { 0x0A, "CALI" },
2186         { 0x0B, "CCLI" },
2187         { 0x0C, "ContListFunc" },
2188         { 0x0D, "CREAG" },
2189         { 0x0E, "DALI" },
2190         { 0x0F, "DCLI" },
2191         { 0x10, "DELGR" },
2192         { 0x11, "FundamentalFeat" },
2193         { 0x12, "FWMSG" },
2194         { 0x13, "GALS" },
2195         { 0x14, "GCLI" },
2196         { 0x15, "GETGM" },
2197         { 0x16, "GETGP" },
2198         { 0x17, "GETLM" },
2199         { 0x18, "GETM" },
2200         { 0x19, "GETPR" },
2201         { 0x1A, "GETSPI" },
2202         { 0x1B, "GETWL" },
2203         { 0x1C, "GLBLU" },
2204         { 0x1D, "GRCHN" },
2205         { 0x1E, "GroupAuthFunc" },
2206         { 0x1F, "GroupFeat" },
2207         { 0x20, "GroupMgmtFunc" },
2208         { 0x21, "GroupUseFunc" },
2209         { 0x22, "IMAuthFunc" },
2210         { 0x23, "IMFeat" },
2211         { 0x24, "IMReceiveFunc" },
2212         { 0x25, "IMSendFunc" },
2213         { 0x26, "INVIT" },
2214         { 0x27, "InviteFunc" },
2215         { 0x28, "MBRAC" },
2216         { 0x29, "MCLS" },
2217         { 0x2A, "MDELIV" },
2218         { 0x2B, "NEWM" },
2219         { 0x2C, "NOTIF" },
2220         { 0x2D, "PresenceAuthFunc" },
2221         { 0x2E, "PresenceDeliverFunc" },
2222         { 0x2F, "PresenceFeat" },
2223         { 0x30, "REACT" },
2224         { 0x31, "REJCM" },
2225         { 0x32, "REJEC" },
2226         { 0x33, "RMVGM" },
2227         { 0x34, "SearchFunc" },
2228         { 0x35, "ServiceFunc" },
2229         { 0x36, "SETD" },
2230         { 0x37, "SETGP" },
2231         { 0x38, "SRCH" },
2232         { 0x39, "STSRC" },
2233         { 0x3A, "SUBGCN" },
2234         { 0x3B, "UPDPR" },
2235         { 0x3C, "WVCSPFeat" },
2236
2237         { 0x00, NULL }
2238 };
2239
2240 /* Client capability code page (0x03) */
2241 static const value_string wbxml_wv_csp_10_tags_cp3[] = {
2242         /* 0x00 -- 0x04 GLOBAL */
2243         { 0x05, "AcceptedCharset" },
2244         { 0x06, "AcceptedContentLength" },
2245         { 0x07, "AcceptedContentType" },
2246         { 0x08, "AcceptedTransferEncoding" },
2247         { 0x09, "AnyContent" },
2248         { 0x0A, "ClientType" },
2249         { 0x0B, "InitialDeliveryMethod" },
2250         { 0x0C, "MultiTrans" },
2251         { 0x0D, "ParserSize" },
2252         { 0x0E, "ServerPollMin" },
2253         { 0x0F, "SupportedBearer" },
2254         { 0x10, "SupportedCIRMethod" },
2255         { 0x11, "TCPAddress" },
2256         { 0x12, "TCPPort" },
2257         { 0x13, "UDPPort" },
2258
2259         { 0x00, NULL }
2260 };
2261
2262 /* Presence primitive code page (0x04) */
2263 static const value_string wbxml_wv_csp_10_tags_cp4[] = {
2264         /* 0x00 -- 0x04 GLOBAL */
2265         { 0x05, "CancelAuth-Request" },
2266         { 0x06, "ContactListProperties" },
2267         { 0x07, "CreateAttributeList-Request" },
2268         { 0x08, "CreateList-Request" },
2269         { 0x09, "DefaultAttributeList" },
2270         { 0x0A, "DefaultContactList" },
2271         { 0x0B, "DefaultList" },
2272         { 0x0C, "DeleteAttributeList-Request" },
2273         { 0x0D, "DeleteList-Request" },
2274         { 0x0E, "GetAttributeList-Request" },
2275         { 0x0F, "GetAttributeList-Response" },
2276         { 0x10, "GetList-Request" },
2277         { 0x11, "GetList-Response" },
2278         { 0x12, "GetPresence-Request" },
2279         { 0x13, "GetPresence-Response" },
2280         { 0x14, "GetWatcherList-Request" },
2281         { 0x15, "GetWatcherList-Response" },
2282         { 0x16, "ListManage-Request" },
2283         { 0x17, "ListManage-Response" },
2284         { 0x18, "Presence" },
2285         { 0x19, "PresenceAuth-Request" },
2286         { 0x1A, "PresenceAuth-Response" },
2287         { 0x1B, "PresenceNotification-Request" },
2288         { 0x1C, "PresenceValueList" },
2289         { 0x1D, "SubscribePresence-Request" },
2290         { 0x1E, "UnsubscribePresence-Request" },
2291         { 0x1F, "UpdatePresence-Request" },
2292
2293         { 0x00, NULL }
2294 };
2295
2296 /* Presence attribute code page (0x05) */
2297 static const value_string wbxml_wv_csp_10_tags_cp5[] = {
2298         /* 0x00 -- 0x04 GLOBAL */
2299         { 0x05, "Accuracy" },
2300         { 0x06, "Address" },
2301         { 0x07, "AddrPref" },
2302         { 0x08, "Alias" },
2303         { 0x09, "Altitude" },
2304         { 0x0A, "Building" },
2305         { 0x0B, "CAddr" },
2306         { 0x0C, "City" },
2307         { 0x0D, "ClientInfo" },
2308         { 0x0E, "ClientProducer" },
2309         { 0x0F, "ClientType" },
2310         { 0x10, "ClientVersion" },
2311         { 0x11, "CommC" },
2312         { 0x12, "CommCap" },
2313         { 0x13, "ContactInfo" },
2314         { 0x14, "ContainedvCard" },
2315         { 0x15, "Country" },
2316         { 0x16, "Crossing1" },
2317         { 0x17, "Crossing2" },
2318         { 0x18, "DevManufacturer" },
2319         { 0x19, "DirectContent" },
2320         { 0x1A, "FreeTextLocation" },
2321         { 0x1B, "GeoLocation" },
2322         { 0x1C, "Language" },
2323         { 0x1D, "Latitude" },
2324         { 0x1E, "Longitude" },
2325         { 0x1F, "Model" },
2326         { 0x20, "NamedArea" },
2327         { 0x21, "OnlineStatus" },
2328         { 0x22, "PLMN" },
2329         { 0x23, "PrefC" },
2330         { 0x24, "PreferredContacts" },
2331         { 0x25, "PreferredLanguage" },
2332         { 0x26, "ReferredContent" },
2333         { 0x27, "ReferredvCard" },
2334         { 0x28, "Registration" },
2335         { 0x29, "StatusContent" },
2336         { 0x2A, "StatusMood" },
2337         { 0x2B, "StatusText" },
2338         { 0x2C, "Street" },
2339         { 0x2D, "TimeZone" },
2340         { 0x2E, "UserAvailability" },
2341
2342         { 0x00, NULL }
2343 };
2344
2345 /* Messaging code page (0x06) */
2346 static const value_string wbxml_wv_csp_10_tags_cp6[] = {
2347         /* 0x00 -- 0x04 GLOBAL */
2348         { 0x05, "BlockList" },
2349         { 0x06, "BlockUser-Request" },
2350         { 0x07, "DeliveryMethod" },
2351         { 0x08, "DeliveryReport" },
2352         { 0x09, "DeliveryReport-Request" },
2353         { 0x0A, "ForwardMessage-Request" },
2354         { 0x0B, "GetBlockedList-Request" },
2355         { 0x0C, "GetBlockedList-Response" },
2356         { 0x0D, "GetMessageList-Request" },
2357         { 0x0E, "GetMessageList-Response" },
2358         { 0x0F, "GetMessage-Request" },
2359         { 0x10, "GetMessage-Response" },
2360         { 0x11, "GrantList" },
2361         { 0x12, "MessageDelivered" },
2362         { 0x13, "MessageInfo" },
2363         { 0x14, "MessageNotification" },
2364         { 0x15, "NewMessage" },
2365         { 0x16, "RejectMessage-Request" },
2366         { 0x17, "SendMessage-Request" },
2367         { 0x18, "SendMessage-Response" },
2368         { 0x19, "SetDeliveryMethod-Request" },
2369
2370         { 0x00, NULL }
2371 };
2372
2373 /* Group code page (0x07) */
2374 static const value_string wbxml_wv_csp_10_tags_cp7[] = {
2375         /* 0x00 -- 0x04 GLOBAL */
2376         { 0x05, "AddGroupMembers-Request" },
2377         { 0x06, "Admin" },
2378         { 0x07, "CreateGroup-Request" },
2379         { 0x08, "DeleteGroup-Request" },
2380         { 0x09, "GetGroupMembers-Request" },
2381         { 0x0A, "GetGroupMembers-Response" },
2382         { 0x0B, "GetGroupProps-Request" },
2383         { 0x0C, "GetGroupProps-Response" },
2384         { 0x0D, "GroupChangeNotice" },
2385         { 0x0E, "GroupProperties" },
2386         { 0x0F, "Joined" },
2387         { 0x10, "JoinedRequest" },
2388         { 0x11, "JoinGroup-Request" },
2389         { 0x12, "JoinGroup-Response" },
2390         { 0x13, "LeaveGroup-Request" },
2391         { 0x14, "LeaveGroup-Response" },
2392         { 0x15, "Left" },
2393         { 0x16, "MemberAccess-Request" },
2394         { 0x17, "Mod" },
2395         { 0x18, "OwnProperties" },
2396         { 0x19, "RejectList-Request" },
2397         { 0x1A, "RejectList-Response" },
2398         { 0x1B, "RemoveGroupMembers-Request" },
2399         { 0x1C, "SetGroupProps-Request" },
2400         { 0x1D, "SubscribeGroupNotice-Request" },
2401         { 0x1E, "SubscribeGroupNotice-Response" },
2402         { 0x1F, "Users" },
2403         { 0x20, "WelcomeNote" },
2404
2405         { 0x00, NULL }
2406 };
2407
2408 /*
2409  * Attribute start tokens
2410  */
2411 /* common code page (0x00) */
2412 static const value_string wbxml_wv_csp_10_attrStart_cp0[] = {
2413         /* 0x00 -- 0x04 GLOBAL */
2414         { 0x05, "xmlns='http://www.wireless-village.org/CSP'" },
2415         { 0x06, "xmlns='http://www.wireless-village.org/PA'" },
2416         { 0x07, "xmlns='http://www.wireless-village.org/TRC'" },
2417
2418         { 0x00, NULL }
2419 };
2420
2421 /*
2422  * Attribute value tokens
2423  */
2424 /* Common value tokens (0x00) */
2425 static const value_string wbxml_wv_csp_10_attrValue_cp0[] = {
2426         /* 0x80 -- 0x84 GLOBAL */
2427         { 0x85, "AccessType" },
2428         { 0x86, "ActiveUsers" },
2429         { 0x87, "Admin" },
2430         { 0x88, "application/" },
2431         { 0x89, "application/vnd.wap.mms-message" },
2432         { 0x8A, "application/x-sms" },
2433         { 0x8B, "BASE64" },
2434         { 0x8C, "Closed" },
2435         { 0x8D, "Default" },
2436         { 0x8E, "DisplayName" },
2437         { 0x8F, "False (No)" },
2438         { 0x90, "Get" },
2439         { 0x91, "Group (GR)" },
2440         { 0x92, "http://" },
2441         { 0x93, "https://" },
2442         { 0x94, "image/" },
2443         { 0x95, "Inband" },
2444         { 0x96, "Instant Messaging (IM)" },
2445         { 0x97, "MaxActiveUsers" },
2446         { 0x98, "Mod" },
2447         { 0x99, "Name" },
2448         { 0x9A, "None" },
2449         { 0x9B, "Notify/Get" },
2450         { 0x9C, "Open" },
2451         { 0x9D, "Outband" },
2452         { 0x9E, "Presence (PR)" },
2453         { 0x9F, "Private" },
2454         { 0xA0, "PrivateMessaging" },
2455         { 0xA1, "PrivilegeLevel" },
2456         { 0xA2, "Public" },
2457         { 0xA3, "Push" },
2458         { 0xA4, "Request" },
2459         { 0xA5, "Response" },
2460         { 0xA6, "ScreenName" },
2461         { 0xA7, "Searchable" },
2462         { 0xA8, "Set" },
2463         { 0xA9, "Shared Content (SC)" },
2464         { 0xAA, "text/" },
2465         { 0xAB, "text/plain" },
2466         { 0xAC, "text/x-vCalendar" },
2467         { 0xAD, "text/x-vCard" },
2468         { 0xAE, "Topic" },
2469         { 0xAF, "True (Yes)" },
2470         { 0xB0, "Type" },
2471         { 0xB1, "Unset" },
2472         { 0xB2, "User (US)" },
2473         { 0xB3, "www.wireless-village.org" },
2474
2475         { 0x00, NULL }
2476 };
2477
2478 /* Access value tokens (0x01) */
2479 static const value_string wbxml_wv_csp_10_attrValue_cp1[] = {
2480         /* 0x80 -- 0x84 GLOBAL */
2481         { 0x85, "GROUP_ID" },
2482         { 0x86, "GROUP_NAME" },
2483         { 0x87, "GROUP_TOPIC" },
2484         { 0x88, "GROUP_USER_ID_JOINED" },
2485         { 0x89, "HTTP" },
2486         { 0x8A, "SMS" },
2487         { 0x8B, "STCP" },
2488         { 0x8C, "SUDP" },
2489         { 0x8D, "USER_ALIAS" },
2490         { 0x8E, "USER_EMAIL_ADDRESS" },
2491         { 0x8F, "USER_FIRST_NAME" },
2492         { 0x90, "USER_ID" },
2493         { 0x91, "USER_LAST_NAME" },
2494         { 0x92, "USER_MOBILE_NUMBER" },
2495         { 0x93, "WAPSMS" },
2496         { 0x94, "WAPUDP" },
2497         { 0x95, "WSP" },
2498
2499         { 0x00, NULL }
2500 };
2501
2502 /* Presence value tokens (0x05) */
2503 static const value_string wbxml_wv_csp_10_attrValue_cp5[] = {
2504         /* 0x80 -- 0x84 GLOBAL */
2505         { 0x85, "ANGRY" },
2506         { 0x86, "ANXIOUS" },
2507         { 0x87, "ASHAMED" },
2508         { 0x88, "AUDIO_CALL" },
2509         { 0x89, "AVAILABLE" },
2510         { 0x8A, "BORED" },
2511         { 0x8B, "CALL" },
2512         { 0x8C, "CLI" },
2513         { 0x8D, "COMPUTER" },
2514         { 0x8E, "DISCREET" },
2515         { 0x8F, "EMAIL" },
2516         { 0x90, "EXCITED" },
2517         { 0x91, "HAPPY" },
2518         { 0x92, "IM" },
2519         { 0x93, "IM_OFFLINE" },
2520         { 0x94, "IM_ONLINE" },
2521         { 0x95, "IN_LOVE" },
2522         { 0x96, "INVINCIBLE" },
2523         { 0x97, "JEALOUS" },
2524         { 0x98, "MMS" },
2525         { 0x99, "MOBILE_PHONE" },
2526         { 0x9A, "NOT_AVAILABLE" },
2527         { 0x9B, "OTHER" },
2528         { 0x9C, "PDA" },
2529         { 0x9D, "SAD" },
2530         { 0x9E, "SLEEPY" },
2531         { 0x9F, "SMS" },
2532         { 0xA0, "VIDEO_CALL" },
2533         { 0xA1, "VIDEO_STREAM" },
2534
2535         { 0x00, NULL }
2536 };
2537
2538
2539 /***** Token code page aggregation *****/
2540 static const value_valuestring wbxml_wv_csp_10_tags[] = {
2541         { 0, wbxml_wv_csp_10_tags_cp0 },
2542         { 1, wbxml_wv_csp_10_tags_cp1 },
2543         { 2, wbxml_wv_csp_10_tags_cp2 },
2544         { 3, wbxml_wv_csp_10_tags_cp3 },
2545         { 4, wbxml_wv_csp_10_tags_cp4 },
2546         { 5, wbxml_wv_csp_10_tags_cp5 },
2547         { 6, wbxml_wv_csp_10_tags_cp6 },
2548         { 7, wbxml_wv_csp_10_tags_cp7 },
2549         { 0, NULL }
2550 };
2551
2552 static const value_valuestring wbxml_wv_csp_10_attrStart[] = {
2553         { 0, wbxml_wv_csp_10_attrStart_cp0 },
2554         { 0, NULL }
2555 };
2556
2557 static const value_valuestring wbxml_wv_csp_10_attrValue[] = {
2558         { 0, wbxml_wv_csp_10_attrValue_cp0 },
2559         { 1, wbxml_wv_csp_10_attrValue_cp1 },
2560         { 5, wbxml_wv_csp_10_attrValue_cp5 },
2561         { 0, NULL }
2562 };
2563
2564 static const wbxml_decoding decode_wv_cspc_10 = {
2565     "Wireless-Village Client-Server Protocol 1.0",
2566     "WV-CSP 1.0",
2567     { NULL, NULL, NULL },
2568     NULL,
2569     wbxml_wv_csp_10_tags,
2570     wbxml_wv_csp_10_attrStart,
2571     wbxml_wv_csp_10_attrValue
2572 };
2573
2574
2575
2576
2577
2578 /* WV-CSP 1.1
2579  * 
2580  * Wireless Village Client Server Protocol
2581  ***************************************/
2582
2583 /*****   Global extension tokens   *****/
2584 static const value_string wbxml_wv_csp_11_global_cp0[] = {
2585         { 0x80, "Common Value" }, /* EXT_T_0 */
2586
2587         { 0x00, NULL }
2588 };
2589
2590 /*****         Tag tokens          *****/
2591 /* Common code page */
2592 static const value_string wbxml_wv_csp_11_tags_cp0[] = {
2593         /* 0x00 -- 0x04 GLOBAL */
2594         { 0x05, "Acceptance" },
2595         { 0x06, "AddList" },
2596         { 0x07, "AddNickList" },
2597         { 0x08, "SName" },              /* Was: Attribute */
2598         { 0x09, "WV-CSP-Message" },     /* Was: AttributeList */
2599         { 0x0A, "ClientID" },
2600         { 0x0B, "Code" },
2601         { 0x0C, "ContactList" },
2602         { 0x0D, "ContentData" },
2603         { 0x0E, "ContentEncoding" },
2604         { 0x0F, "ContentSize" },
2605         { 0x10, "ContentType" },
2606         { 0x11, "DateTime" },
2607         { 0x12, "Description" },
2608         { 0x13, "DetailedResult" },
2609         { 0x14, "EntityList" },
2610         { 0x15, "Group" },
2611         { 0x16, "GroupID" },
2612         { 0x17, "GroupList" },
2613         { 0x18, "InUse" },
2614         { 0x19, "Logo" },
2615         { 0x1A, "MessageCount" },
2616         { 0x1B, "MessageID" },
2617         { 0x1C, "MessageURI" },
2618         { 0x1D, "MSISDN" },
2619         { 0x1E, "Name" },
2620         { 0x1F, "NickList" },
2621         { 0x20, "NickName" },
2622         { 0x21, "Poll" },
2623         { 0x22, "Presence" },
2624         { 0x23, "PresenceSubList" },
2625         { 0x24, "PresenceValue" },
2626         { 0x25, "Property" },
2627         { 0x26, "Qualifier" },
2628         { 0x27, "Recipient" },
2629         { 0x28, "RemoveList" },
2630         { 0x29, "RemoveNickList" },
2631         { 0x2A, "Result" },
2632         { 0x2B, "ScreenName" },
2633         { 0x2C, "Sender" },
2634         { 0x2D, "Session" },
2635         { 0x2E, "SessionDescriptor" },
2636         { 0x2F, "SessionID" },
2637         { 0x30, "SessionType" },
2638         { 0x31, "Status" },
2639         { 0x32, "Transaction" },
2640         { 0x33, "TransactionContent" },
2641         { 0x34, "TransactionDescriptor" },
2642         { 0x35, "TransactionID" },
2643         { 0x36, "TransactionMode" },
2644         { 0x37, "URL" },
2645         { 0x38, "URLList" },
2646         { 0x39, "User" },
2647         { 0x3A, "UserID" },
2648         { 0x3B, "UserList" },
2649         { 0x3C, "Validity" },
2650         { 0x3D, "Value" },
2651         /* 0x3E - Removed: WV-CSP-Message */
2652
2653         { 0x00, NULL }
2654 };
2655
2656 /* Access code page */
2657 static const value_string wbxml_wv_csp_11_tags_cp1[] = {
2658         /* 0x00 -- 0x04 GLOBAL */
2659         { 0x05, "AllFunctions" },
2660         { 0x06, "AllFunctionsRequest" },
2661         { 0x07, "CancelInvite-Request" },
2662         { 0x08, "CancelInviteUser-Request" },
2663         { 0x09, "Capability" },
2664         { 0x0A, "CapabilityList" },
2665         { 0x0B, "CapabilityRequest" },
2666         { 0x0C, "ClientCapability-Request" },
2667         { 0x0D, "ClientCapability-Response" },
2668         { 0x0E, "DigestBytes" },
2669         { 0x0F, "DigestSchema" },
2670         { 0x10, "Disconnect" },
2671         { 0x11, "Functions" },
2672         { 0x12, "GetSPInfo-Request" },
2673         { 0x13, "GetSPInfo-Response" },
2674         { 0x14, "InviteID" },
2675         { 0x15, "InviteNote" },
2676         { 0x16, "Invite-Request" },
2677         { 0x17, "Invite-Response" },
2678         { 0x18, "InviteType" },
2679         { 0x19, "InviteUser-Request" },
2680         { 0x1A, "InviteUser-Response" },
2681         { 0x1B, "KeepAlive-Request" },
2682         { 0x1C, "KeepAliveTime" },
2683         { 0x1D, "Login-Request" },
2684         { 0x1E, "Login-Response" },
2685         { 0x1F, "Logout-Request" },
2686         { 0x20, "Nonce" },
2687         { 0x21, "Password" },
2688         { 0x22, "Polling-Request" },
2689         { 0x23, "ResponseNote" },
2690         { 0x24, "SearchElement" },
2691         { 0x25, "SearchFindings" },
2692         { 0x26, "SearchID" },
2693         { 0x27, "SearchIndex" },
2694         { 0x28, "SearchLimit" },
2695         { 0x29, "KeepAlive-Response" }, /* Was: SearchOnlineStatus */
2696         { 0x2A, "SearchPairList" },
2697         { 0x2B, "Search-Request" },
2698         { 0x2C, "Search-Response" },
2699         { 0x2D, "SearchResult" },
2700         { 0x2E, "Service-Request" },
2701         { 0x2F, "Service-Response" },
2702         { 0x30, "SessionCookie" },
2703         { 0x31, "StopSearch-Request" },
2704         { 0x32, "TimeToLive" },
2705         /* New in WV-CSP 1.1 */
2706         { 0x33, "SearchString" },
2707         { 0x34, "CompletionFlag" },
2708
2709         { 0x00, NULL }
2710 };
2711
2712 /* Service code page */
2713 /* Same as cp2 of WV-CSP 1.0 */
2714 #define wbxml_wv_csp_11_tags_cp2 wbxml_wv_csp_10_tags_cp2
2715
2716 /* Client capability code page */
2717 static const value_string wbxml_wv_csp_11_tags_cp3[] = {
2718         /* 0x00 -- 0x04 GLOBAL */
2719         { 0x05, "AcceptedCharset" },
2720         { 0x06, "AcceptedContentLength" },
2721         { 0x07, "AcceptedContentType" },
2722         { 0x08, "AcceptedTransferEncoding" },
2723         { 0x09, "AnyContent" },
2724         { 0x0A, "DefaultLanguage" },    /* Was: ClientType */
2725         { 0x0B, "InitialDeliveryMethod" },
2726         { 0x0C, "MultiTrans" },
2727         { 0x0D, "ParserSize" },
2728         { 0x0E, "ServerPollMin" },
2729         { 0x0F, "SupportedBearer" },
2730         { 0x10, "SupportedCIRMethod" },
2731         { 0x11, "TCPAddress" },
2732         { 0x12, "TCPPort" },
2733         { 0x13, "UDPPort" },
2734
2735         { 0x00, NULL }
2736 };
2737
2738 /* Presence primitive code page */
2739 static const value_string wbxml_wv_csp_11_tags_cp4[] = {
2740         /* 0x00 -- 0x04 GLOBAL */
2741         { 0x05, "CancelAuth-Request" },
2742         { 0x06, "ContactListProperties" },
2743         { 0x07, "CreateAttributeList-Request" },
2744         { 0x08, "CreateList-Request" },
2745         { 0x09, "DefaultAttributeList" },
2746         { 0x0A, "DefaultContactList" },
2747         { 0x0B, "DefaultList" },
2748         { 0x0C, "DeleteAttributeList-Request" },
2749         { 0x0D, "DeleteList-Request" },
2750         { 0x0E, "GetAttributeList-Request" },
2751         { 0x0F, "GetAttributeList-Response" },
2752         { 0x10, "GetList-Request" },
2753         { 0x11, "GetList-Response" },
2754         { 0x12, "GetPresence-Request" },
2755         { 0x13, "GetPresence-Response" },
2756         { 0x14, "GetWatcherList-Request" },
2757         { 0x15, "GetWatcherList-Response" },
2758         { 0x16, "ListManage-Request" },
2759         { 0x17, "ListManage-Response" },
2760         { 0x18, "UnsubscribePresence-Request" },        /* Was: Presence */
2761         { 0x19, "PresenceAuth-Request" },
2762         { 0x1A, "PresenceAuth-User" },          /* Was: PresenceAuth-Response */
2763         { 0x1B, "PresenceNotification-Request" },
2764         { 0x1C, "UpdatePresence-Request" },     /* Was: PresenceValueList */
2765         { 0x1D, "SubscribePresence-Request" },
2766         /* 0x1E - Removed: UnsubscribePresence-Request */
2767         /* 0x1F - Removed: UpdatePresence-Request */
2768
2769         { 0x00, NULL }
2770 };
2771
2772 /* Presence attribute code page */
2773 static const value_string wbxml_wv_csp_11_tags_cp5[] = {
2774         /* 0x00 -- 0x04 GLOBAL */
2775         { 0x05, "Accuracy" },
2776         { 0x06, "Address" },
2777         { 0x07, "AddrPref" },
2778         { 0x08, "Alias" },
2779         { 0x09, "Altitude" },
2780         { 0x0A, "Building" },
2781         { 0x0B, "Caddr" },
2782         { 0x0C, "City" },
2783         { 0x0D, "ClientInfo" },
2784         { 0x0E, "ClientProducer" },
2785         { 0x0F, "ClientType" },
2786         { 0x10, "ClientVersion" },
2787         { 0x11, "CommC" },
2788         { 0x12, "CommCap" },
2789         { 0x13, "ContactInfo" },
2790         { 0x14, "ContainedvCard" },
2791         { 0x15, "Country" },
2792         { 0x16, "Crossing1" },
2793         { 0x17, "Crossing2" },
2794         { 0x18, "DevManufacturer" },
2795         { 0x19, "DirectContent" },
2796         { 0x1A, "FreeTextLocation" },
2797         { 0x1B, "GeoLocation" },
2798         { 0x1C, "Language" },
2799         { 0x1D, "Latitude" },
2800         { 0x1E, "Longitude" },
2801         { 0x1F, "Model" },
2802         { 0x20, "NamedArea" },
2803         { 0x21, "OnlineStatus" },
2804         { 0x22, "PLMN" },
2805         { 0x23, "PrefC" },
2806         { 0x24, "PreferredContacts" },
2807         { 0x25, "PreferredLanguage" },
2808         { 0x26, "ReferredContent" },
2809         { 0x27, "ReferredvCard" },
2810         { 0x28, "Registration" },
2811         { 0x29, "StatusContent" },
2812         { 0x2A, "StatusMood" },
2813         { 0x2B, "StatusText" },
2814         { 0x2C, "Street" },
2815         { 0x2D, "TimeZone" },
2816         { 0x2E, "UserAvailability" },
2817         /* New in WV-CSP 1.1 */
2818         { 0x2F, "Cap" },
2819         { 0x30, "Cname" },
2820         { 0x31, "Contact" },
2821         { 0x32, "Cpriority" },
2822         { 0x33, "Cstatus" },
2823         { 0x34, "Note" },
2824         { 0x35, "Zone" },
2825
2826         { 0x00, NULL }
2827 };
2828
2829 /* Messaging code page */
2830 static const value_string wbxml_wv_csp_11_tags_cp6[] = {
2831         /* 0x00 -- 0x04 GLOBAL */
2832         { 0x05, "BlockList" },
2833         { 0x06, "BlockUser-Request" },
2834         { 0x07, "DeliveryMethod" },
2835         { 0x08, "DeliveryReport" },
2836         { 0x09, "DeliveryReport-Request" },
2837         { 0x0A, "ForwardMessage-Request" },
2838         { 0x0B, "GetBlockedList-Request" },
2839         { 0x0C, "GetBlockedList-Response" },
2840         { 0x0D, "GetMessageList-Request" },
2841         { 0x0E, "GetMessageList-Response" },
2842         { 0x0F, "GetMessage-Request" },
2843         { 0x10, "GetMessage-Response" },
2844         { 0x11, "GrantList" },
2845         { 0x12, "MessageDelivered" },
2846         { 0x13, "MessageInfo" },
2847         { 0x14, "MessageNotification" },
2848         { 0x15, "NewMessage" },
2849         { 0x16, "RejectMessage-Request" },
2850         { 0x17, "SendMessage-Request" },
2851         { 0x18, "SendMessage-Response" },
2852         { 0x19, "SetDeliveryMethod-Request" },
2853         /* New in WV-CSP 1.1 */
2854         { 0x1A, "DeliveryTime" },
2855
2856         { 0x00, NULL }
2857 };
2858
2859 /* Group code page */
2860 static const value_string wbxml_wv_csp_11_tags_cp7[] = {
2861         /* 0x00 -- 0x04 GLOBAL */
2862         { 0x05, "AddGroupMembers-Request" },
2863         { 0x06, "Admin" },
2864         { 0x07, "CreateGroup-Request" },
2865         { 0x08, "DeleteGroup-Request" },
2866         { 0x09, "GetGroupMembers-Request" },
2867         { 0x0A, "GetGroupMembers-Response" },
2868         { 0x0B, "GetGroupProps-Request" },
2869         { 0x0C, "GetGroupProps-Response" },
2870         { 0x0D, "GroupChangeNotice" },
2871         { 0x0E, "GroupProperties" },
2872         { 0x0F, "Joined" },
2873         { 0x10, "JoinedRequest" },
2874         { 0x11, "JoinGroup-Request" },
2875         { 0x12, "JoinGroup-Response" },
2876         { 0x13, "LeaveGroup-Request" },
2877         { 0x14, "LeaveGroup-Response" },
2878         { 0x15, "Left" },
2879         { 0x16, "MemberAccess-Request" },
2880         { 0x17, "Mod" },
2881         { 0x18, "OwnProperties" },
2882         { 0x19, "RejectList-Request" },
2883         { 0x1A, "RejectList-Response" },
2884         { 0x1B, "RemoveGroupMembers-Request" },
2885         { 0x1C, "SetGroupProps-Request" },
2886         { 0x1D, "SubscribeGroupNotice-Request" },
2887         { 0x1E, "SubscribeGroupNotice-Response" },
2888         { 0x1F, "Users" },
2889         { 0x20, "WelcomeNote" },
2890         /* New in WV-CSP 1.1 */
2891         { 0x21, "JoinGroup" },
2892         { 0x22, "SubscribeNotification" },
2893         { 0x23, "SubscribeType" },
2894
2895         { 0x00, NULL }
2896 };
2897
2898 /*****    Attribute Start tokens   *****/
2899 /* Common code page */
2900 /* Same as cp0 of WV-CSP 1.0 */
2901 #define wbxml_wv_csp_11_attrStart_cp0 wbxml_wv_csp_10_attrStart_cp0
2902
2903 /*****    Attribute Value tokens   *****/
2904 /*
2905  * Element value tokens
2906  *
2907  * NOTE - WV-CSP uses the EXT_T_0 token in a peculiar way: the mb_u_int32
2908  * does *not* reference an offset in the string table, but it refers to
2909  * the index in the following value_string.
2910  * 
2911  * Please note that:
2912  *  - Values 'T' and 'F' are Boolean values representing "True" and "False"
2913  *    (or "Yes" and "No" in some circumstances) respectively.
2914  *  - Values 'GR', 'IM', 'PR', 'SC', 'GM' and 'US' are enumerated values
2915  *    representing "Group", "Instant Messaging", "Presence", "Shared Content",
2916  *    "Group membership" and "User" respectively.
2917  *  - Values 'G', 'S' and 'U' are enumerated values representing "Get", "Set"
2918  *    and "Unset" respectively.
2919  *  - Values 'N' and 'P' are enumerated values representing "Notify/Get" and
2920  *    "Push" respectively.
2921  *
2922  * I repeat: this is NOT a attrValue[] array hence it is not called
2923  * wbxml_wv_XXX but vals_wv_XXX.
2924  *
2925  * Result: the attribute value token definitions from WV-CSP 1.0 are dropped.
2926  */
2927 static const value_string vals_wv_csp_11_element_value_tokens[] = {
2928         /*
2929          * Common value tokens
2930          */
2931         { 0x00, "AccessType" },
2932         { 0x01, "ActiveUsers" },
2933         { 0x02, "Admin" },
2934         { 0x03, "application/" },
2935         { 0x04, "application/vnd.wap.mms-message" },
2936         { 0x05, "application/x-sms" },
2937         { 0x06, "AutoJoin" },
2938         { 0x07, "BASE64" },
2939         { 0x08, "Closed" },
2940         { 0x09, "Default" },
2941         { 0x0A, "DisplayName" },
2942         { 0x0B, "F" },
2943         { 0x0C, "G" },
2944         { 0x0D, "GR" },
2945         { 0x0E, "http://" },
2946         { 0x0F, "https://" },
2947         { 0x10, "image/" },
2948         { 0x11, "Inband" },
2949         { 0x12, "IM" },
2950         { 0x13, "MaxActiveUsers" },
2951         { 0x14, "Mod" },
2952         { 0x15, "Name" },
2953         { 0x16, "None" },
2954         { 0x17, "N" },
2955         { 0x18, "Open" },
2956         { 0x19, "Outband" },
2957         { 0x1A, "PR" },
2958         { 0x1B, "Private" },
2959         { 0x1C, "PrivateMessaging" },
2960         { 0x1D, "PrivilegeLevel" },
2961         { 0x1E, "Public" },
2962         { 0x1F, "P" },
2963         { 0x20, "Request" },
2964         { 0x21, "Response" },
2965         { 0x22, "Restricted" },
2966         { 0x23, "ScreenName" },
2967         { 0x24, "Searchable" },
2968         { 0x25, "S" },
2969         { 0x26, "SC" },
2970         { 0x27, "text/" },
2971         { 0x28, "text/plain" },
2972         { 0x29, "text/x-vCalendar" },
2973         { 0x2A, "text/x-vCard" },
2974         { 0x2B, "Topic" },
2975         { 0x2C, "T" },
2976         { 0x2D, "Type" },
2977         { 0x2E, "U" },
2978         { 0x2F, "US" },
2979         { 0x30, "www.wireless-village.org" },
2980         /*
2981          * Access value tokens
2982          */
2983         { 0x3D, "GROUP_ID" },
2984         { 0x3E, "GROUP_NAME" },
2985         { 0x3F, "GROUP_TOPIC" },
2986         { 0x40, "GROUP_USER_ID_JOINED" },
2987         { 0x41, "GROUP_USER_ID_OWNER" },
2988         { 0x42, "HTTP" },
2989         { 0x43, "SMS" },
2990         { 0x44, "STCP" },
2991         { 0x45, "SUDP" },
2992         { 0x46, "USER_ALIAS" },
2993         { 0x47, "USER_EMAIL_ADDRESS" },
2994         { 0x48, "USER_FIRST_NAME" },
2995         { 0x49, "USER_ID" },
2996         { 0x4A, "USER_LAST_NAME" },
2997         { 0x4B, "USER_MOBILE_NUMBER" },
2998         { 0x4C, "USER_ONLINE_STATUS" },
2999         { 0x4D, "WAPSMS" },
3000         { 0x4E, "WAPUDP" },
3001         { 0x4F, "WSP" },
3002         /*
3003          * Presence value tokens
3004          */
3005         { 0x5B, "ANGRY" },
3006         { 0x5C, "ANXIOUS" },
3007         { 0x5D, "ASHAMED" },
3008         { 0x5E, "AUDIO_CALL" },
3009         { 0x5F, "AVAILABLE" },
3010         { 0x60, "BORED" },
3011         { 0x61, "CALL" },
3012         { 0x62, "CLI" },
3013         { 0x63, "COMPUTER" },
3014         { 0x64, "DISCREET" },
3015         { 0x65, "EMAIL" },
3016         { 0x66, "EXCITED" },
3017         { 0x67, "HAPPY" },
3018         { 0x68, "IM" },
3019         { 0x69, "IM_OFFLINE" },
3020         { 0x6A, "IM_ONLINE" },
3021         { 0x6B, "IN_LOVE" },
3022         { 0x6C, "INVINCIBLE" },
3023         { 0x6D, "JEALOUS" },
3024         { 0x6E, "MMS" },
3025         { 0x6F, "MOBILE_PHONE" },
3026         { 0x70, "NOT_AVAILABLE" },
3027         { 0x71, "OTHER" },
3028         { 0x72, "PDA" },
3029         { 0x73, "SAD" },
3030         { 0x74, "SLEEPY" },
3031         { 0x75, "SMS" },
3032         { 0x76, "VIDEO_CALL" },
3033         { 0x77, "VIDEO_STREAM" },
3034
3035         { 0x00, NULL }
3036 };
3037
3038
3039 /***** Token code page aggregation *****/
3040
3041 static char *
3042 ext_t_0_wv_cspc_11(tvbuff_t *tvb _U_, guint32 value, guint32 str_tbl _U_)
3043 {
3044     char *str = g_strdup_printf("Common Value: '%s'",
3045             val_to_str(value, vals_wv_csp_11_element_value_tokens,
3046                 "<Unknown WV-CSP 1.1 Common Value token 0x%X>"));
3047     return str;
3048 }
3049
3050 static const value_valuestring wbxml_wv_csp_11_global[] = {
3051         { 0, wbxml_wv_csp_11_global_cp0 },
3052         { 0, NULL }
3053 };
3054
3055 static const value_valuestring wbxml_wv_csp_11_tags[] = {
3056         { 0, wbxml_wv_csp_11_tags_cp0 },
3057         { 1, wbxml_wv_csp_11_tags_cp1 },
3058         { 2, wbxml_wv_csp_11_tags_cp2 },
3059         { 3, wbxml_wv_csp_11_tags_cp3 },
3060         { 4, wbxml_wv_csp_11_tags_cp4 },
3061         { 5, wbxml_wv_csp_11_tags_cp5 },
3062         { 6, wbxml_wv_csp_11_tags_cp6 },
3063         { 7, wbxml_wv_csp_11_tags_cp7 },
3064         { 0, NULL }
3065 };
3066
3067 static const value_valuestring wbxml_wv_csp_11_attrStart[] = {
3068         { 0, wbxml_wv_csp_11_attrStart_cp0 },
3069         { 0, NULL }
3070 };
3071
3072 static const wbxml_decoding decode_wv_cspc_11 = {
3073     "Wireless-Village Client-Server Protocol 1.1",
3074     "WV-CSP 1.1",
3075     { ext_t_0_wv_cspc_11, NULL, NULL },
3076     wbxml_wv_csp_11_global,
3077     wbxml_wv_csp_11_tags,
3078     wbxml_wv_csp_11_attrStart,
3079     NULL
3080 };
3081
3082
3083
3084
3085
3086 /* WV-CSP 1.2
3087  * 
3088  * Wireless Village Client Server Protocol
3089  ***************************************/
3090 #ifdef Remove_this_comment_when_WV_CSP_will_be_an_approved_spec
3091
3092 /*****   Global extension tokens   *****/
3093 /* Same as WV-CSP 1.1 */
3094
3095 /*****         Tag tokens          *****/
3096 /* Common code page */
3097 /* Same as cp0 of WV-CSP 1.1 */
3098 #define wbxml_wv_csp_12_tags_cp0 wbxml_wv_csp_11_tags_cp0
3099 /* Note that the table continues in code page 0x09 */
3100
3101 /* Access code page (0x01) */
3102 static const value_string wbxml_wv_csp_12_tags_cp1[] = {
3103         /* 0x00 -- 0x04 GLOBAL */
3104         { 0x05, "AllFunctions" },
3105         { 0x06, "AllFunctionsRequest" },
3106         { 0x07, "CancelInvite-Request" },
3107         { 0x08, "CancelInviteUser-Request" },
3108         { 0x09, "Capability" },
3109         { 0x0A, "CapabilityList" },
3110         { 0x0B, "CapabilityRequest" },
3111         { 0x0C, "ClientCapability-Request" },
3112         { 0x0D, "ClientCapability-Response" },
3113         { 0x0E, "DigestBytes" },
3114         { 0x0F, "DigestSchema" },
3115         { 0x10, "Disconnect" },
3116         { 0x11, "Functions" },
3117         { 0x12, "GetSPInfo-Request" },
3118         { 0x13, "GetSPInfo-Response" },
3119         { 0x14, "InviteID" },
3120         { 0x15, "InviteNote" },
3121         { 0x16, "Invite-Request" },
3122         { 0x17, "Invite-Response" },
3123         { 0x18, "InviteType" },
3124         { 0x19, "InviteUser-Request" },
3125         { 0x1A, "InviteUser-Response" },
3126         { 0x1B, "KeepAlive-Request" },
3127         { 0x1C, "KeepAliveTime" },
3128         { 0x1D, "Login-Request" },
3129         { 0x1E, "Login-Response" },
3130         { 0x1F, "Logout-Request" },
3131         { 0x20, "Nonce" },
3132         { 0x21, "Password" },
3133         { 0x22, "Polling-Request" },
3134         { 0x23, "ResponseNote" },
3135         { 0x24, "SearchElement" },
3136         { 0x25, "SearchFindings" },
3137         { 0x26, "SearchID" },
3138         { 0x27, "SearchIndex" },
3139         { 0x28, "SearchLimit" },
3140         { 0x29, "KeepAlive-Response" },
3141         { 0x2A, "SearchPairList" },
3142         { 0x2B, "Search-Request" },
3143         { 0x2C, "Search-Response" },
3144         { 0x2D, "SearchResult" },
3145         { 0x2E, "Service-Request" },
3146         { 0x2F, "Service-Response" },
3147         { 0x30, "SessionCookie" },
3148         { 0x31, "StopSearch-Request" },
3149         { 0x32, "TimeToLive" },
3150         /* New in WV-CSP 1.1 */
3151         { 0x33, "SearchString" },
3152         { 0x34, "CompletionFlag" },
3153         /* New in WV-CSP 1.2 */
3154         { 0x36, "ReceiveList" },
3155         { 0x37, "VerifyID-Request" },
3156         { 0x38, "Extended-Request" },
3157         { 0x39, "Extended-Response" },
3158         { 0x3A, "AgreedCapabilityList" },
3159         { 0x3B, "ExtendedData" },
3160         { 0x3C, "OtherServer" },
3161         { 0x3D, "PresenceAttributeNSName" },
3162         { 0x3E, "SessionNSName" },
3163         { 0x3F, "TransactionNSName" },
3164
3165         { 0x00, NULL }
3166 };
3167 /* Note that the table continues in code page 0x0A */
3168
3169 /* Service code page (0x02) */
3170 static const value_string wbxml_wv_csp_12_tags_cp2[] = {
3171         /* 0x00 -- 0x04 GLOBAL */
3172         { 0x05, "ADDGM" },
3173         { 0x06, "AttListFunc" },
3174         { 0x07, "BLENT" },
3175         { 0x08, "CAAUT" },
3176         { 0x09, "CAINV" },
3177         { 0x0A, "CALI" },
3178         { 0x0B, "CCLI" },
3179         { 0x0C, "ContListFunc" },
3180         { 0x0D, "CREAG" },
3181         { 0x0E, "DALI" },
3182         { 0x0F, "DCLI" },
3183         { 0x10, "DELGR" },
3184         { 0x11, "FundamentalFeat" },
3185         { 0x12, "FWMSG" },
3186         { 0x13, "GALS" },
3187         { 0x14, "GCLI" },
3188         { 0x15, "GETGM" },
3189         { 0x16, "GETGP" },
3190         { 0x17, "GETLM" },
3191         { 0x18, "GETM" },
3192         { 0x19, "GETPR" },
3193         { 0x1A, "GETSPI" },
3194         { 0x1B, "GETWL" },
3195         { 0x1C, "GLBLU" },
3196         { 0x1D, "GRCHN" },
3197         { 0x1E, "GroupAuthFunc" },
3198         { 0x1F, "GroupFeat" },
3199         { 0x20, "GroupMgmtFunc" },
3200         { 0x21, "GroupUseFunc" },
3201         { 0x22, "IMAuthFunc" },
3202         { 0x23, "IMFeat" },
3203         { 0x24, "IMReceiveFunc" },
3204         { 0x25, "IMSendFunc" },
3205         { 0x26, "INVIT" },
3206         { 0x27, "InviteFunc" },
3207         { 0x28, "MBRAC" },
3208         { 0x29, "MCLS" },
3209         { 0x2A, "MDELIV" },
3210         { 0x2B, "NEWM" },
3211         { 0x2C, "NOTIF" },
3212         { 0x2D, "PresenceAuthFunc" },
3213         { 0x2E, "PresenceDeliverFunc" },
3214         { 0x2F, "PresenceFeat" },
3215         { 0x30, "REACT" },
3216         { 0x31, "REJCM" },
3217         { 0x32, "REJEC" },
3218         { 0x33, "RMVGM" },
3219         { 0x34, "SearchFunc" },
3220         { 0x35, "ServiceFunc" },
3221         { 0x36, "SETD" },
3222         { 0x37, "SETGP" },
3223         { 0x38, "SRCH" },
3224         { 0x39, "STSRC" },
3225         { 0x3A, "SUBGCN" },
3226         { 0x3B, "UPDPR" },
3227         { 0x3C, "WVCSPFeat" },
3228         /* New in WV-CSP 1.2 */
3229         { 0x3D, "MF" },
3230         { 0x3E, "MG" },
3231         { 0x3E, "VRID" }, /* Duplicate, and cp2 is full --> Will move to cp8? */
3232         { 0x3F, "MM" },
3233
3234         { 0x00, NULL }
3235 };
3236 /* Note that the table continues in code page 0x08 */
3237
3238 /* Client capability code page (0x03) */
3239 /* Same as cp3 of WV-CSP 1.0 */
3240 #define wbxml_wv_csp_12_tags_cp3 wbxml_wv_csp_10_tags_cp3
3241
3242 /* Presence primitive code page (0x04) */
3243 static const value_string wbxml_wv_csp_12_tags_cp4[] = {
3244         /* 0x00 -- 0x04 GLOBAL */
3245         { 0x05, "CancelAuth-Request" },
3246         { 0x06, "ContactListProperties" },
3247         { 0x07, "CreateAttributeList-Request" },
3248         { 0x08, "CreateList-Request" },
3249         { 0x09, "DefaultAttributeList" },
3250         { 0x0A, "DefaultContactList" },
3251         { 0x0B, "DefaultList" },
3252         { 0x0C, "DeleteAttributeList-Request" },
3253         { 0x0D, "DeleteList-Request" },
3254         { 0x0E, "GetAttributeList-Request" },
3255         { 0x0F, "GetAttributeList-Response" },
3256         { 0x10, "GetList-Request" },
3257         { 0x11, "GetList-Response" },
3258         { 0x12, "GetPresence-Request" },
3259         { 0x13, "GetPresence-Response" },
3260         { 0x14, "GetWatcherList-Request" },
3261         { 0x15, "GetWatcherList-Response" },
3262         { 0x16, "ListManage-Request" },
3263         { 0x17, "ListManage-Response" },
3264         { 0x18, "UnsubscribePresence-Request" },
3265         { 0x19, "PresenceAuth-Request" },
3266         { 0x1A, "PresenceAuth-User" },
3267         { 0x1B, "PresenceNotification-Request" },
3268         { 0x1C, "UpdatePresence-Request" },
3269         { 0x1D, "SubscribePresence-Request" },
3270         /* New in WV-CSP 1.2 */
3271         { 0x1E, "Auto-Subscribe" },
3272         /* 0x1E was defined in WV-CSP 1.0: UnsubscribePresence-Request */
3273         { 0x1F, "GetReactiveAuthStatus-Request" },
3274         /* 0x1F was defined in WV-CSP 1.0: UpdatePresence-Request */
3275         { 0x20, "GetReactiveAuthStatus-Response" },
3276
3277         { 0x00, NULL }
3278 };
3279
3280 /* Presence attribute code page (0x05) */
3281 static const value_string wbxml_wv_csp_12_tags_cp5[] = {
3282         /* 0x00 -- 0x04 GLOBAL */
3283         { 0x05, "Accuracy" },
3284         { 0x06, "Address" },
3285         { 0x07, "AddrPref" },
3286         { 0x08, "Alias" },
3287         { 0x09, "Altitude" },
3288         { 0x0A, "Building" },
3289         { 0x0B, "Caddr" },
3290         { 0x0C, "City" },
3291         { 0x0D, "ClientInfo" },
3292         { 0x0E, "ClientProducer" },
3293         { 0x0F, "ClientType" },
3294         { 0x10, "ClientVersion" },
3295         { 0x11, "CommC" },
3296         { 0x12, "CommCap" },
3297         { 0x13, "ContactInfo" },
3298         { 0x14, "ContainedvCard" },
3299         { 0x15, "Country" },
3300         { 0x16, "Crossing1" },
3301         { 0x17, "Crossing2" },
3302         { 0x18, "DevManufacturer" },
3303         { 0x19, "DirectContent" },
3304         { 0x1A, "FreeTextLocation" },
3305         { 0x1B, "GeoLocation" },
3306         { 0x1C, "Language" },
3307         { 0x1D, "Latitude" },
3308         { 0x1E, "Longitude" },
3309         { 0x1F, "Model" },
3310         { 0x20, "NamedArea" },
3311         { 0x21, "OnlineStatus" },
3312         { 0x22, "PLMN" },
3313         { 0x23, "PrefC" },
3314         { 0x24, "PreferredContacts" },
3315         { 0x25, "PreferredLanguage" },
3316         { 0x26, "ReferredContent" },
3317         { 0x27, "ReferredvCard" },
3318         { 0x28, "Registration" },
3319         { 0x29, "StatusContent" },
3320         { 0x2A, "StatusMood" },
3321         { 0x2B, "StatusText" },
3322         { 0x2C, "Street" },
3323         { 0x2D, "TimeZone" },
3324         { 0x2E, "UserAvailability" },
3325         /* New in WV-CSP 1.1 */
3326         { 0x2F, "Cap" },
3327         { 0x30, "Cname" },
3328         { 0x31, "Contact" },
3329         { 0x32, "Cpriority" },
3330         { 0x33, "Cstatus" },
3331         { 0x34, "Note" },
3332         { 0x35, "Zone" },
3333         /* New in WV-CSP 1.2 */
3334         { 0x36, "ContentType" },
3335         { 0x37, "Inf_link" },
3336         { 0x38, "InfoLink" },
3337         { 0x39, "Link" },
3338         { 0x3A, "Text" },
3339
3340         { 0x00, NULL }
3341 };
3342
3343 /* Messaging code page (0x06) */
3344 static const value_string wbxml_wv_csp_12_tags_cp6[] = {
3345         /* 0x00 -- 0x04 GLOBAL */
3346         { 0x05, "BlockList" },
3347         { 0x06, "BlockEntity-Request" }, /* Was: BlockUser-Request */
3348         { 0x07, "DeliveryMethod" },
3349         { 0x08, "DeliveryReport" },
3350         { 0x09, "DeliveryReport-Request" },
3351         { 0x0A, "ForwardMessage-Request" },
3352         { 0x0B, "GetBlockedList-Request" },
3353         { 0x0C, "GetBlockedList-Response" },
3354         { 0x0D, "GetMessageList-Request" },
3355         { 0x0E, "GetMessageList-Response" },
3356         { 0x0F, "GetMessage-Request" },
3357         { 0x10, "GetMessage-Response" },
3358         { 0x11, "GrantList" },
3359         { 0x12, "MessageDelivered" },
3360         { 0x13, "MessageInfo" },
3361         { 0x14, "MessageNotification" },
3362         { 0x15, "NewMessage" },
3363         { 0x16, "RejectMessage-Request" },
3364         { 0x17, "SendMessage-Request" },
3365         { 0x18, "SendMessage-Response" },
3366         { 0x19, "SetDeliveryMethod-Request" },
3367         { 0x1A, "DeliveryTime" },
3368
3369         { 0x00, NULL }
3370 };
3371
3372 /* Group code page (0x07) */
3373 static const value_string wbxml_wv_csp_12_tags_cp7[] = {
3374         /* 0x00 -- 0x04 GLOBAL */
3375         { 0x05, "AddGroupMembers-Request" },
3376         { 0x06, "Admin" },
3377         { 0x07, "CreateGroup-Request" },
3378         { 0x08, "DeleteGroup-Request" },
3379         { 0x09, "GetGroupMembers-Request" },
3380         { 0x0A, "GetGroupMembers-Response" },
3381         { 0x0B, "GetGroupProps-Request" },
3382         { 0x0C, "GetGroupProps-Response" },
3383         { 0x0D, "GroupChangeNotice" },
3384         { 0x0E, "GroupProperties" },
3385         { 0x0F, "Joined" },
3386         { 0x10, "JoinedRequest" },
3387         { 0x11, "JoinGroup-Request" },
3388         { 0x12, "JoinGroup-Response" },
3389         { 0x13, "LeaveGroup-Request" },
3390         { 0x14, "LeaveGroup-Response" },
3391         { 0x15, "Left" },
3392         { 0x16, "MemberAccess-Request" },
3393         { 0x17, "Mod" },
3394         { 0x18, "OwnProperties" },
3395         { 0x19, "RejectList-Request" },
3396         { 0x1A, "RejectList-Response" },
3397         { 0x1B, "RemoveGroupMembers-Request" },
3398         { 0x1C, "SetGroupProps-Request" },
3399         { 0x1D, "SubscribeGroupNotice-Request" },
3400         { 0x1E, "SubscribeGroupNotice-Response" },
3401         { 0x1F, "Users" },
3402         { 0x20, "WelcomeNote" },
3403         /* New in WV-CSP 1.1 */
3404         { 0x21, "JoinGroup" },
3405         { 0x22, "SubscribeNotification" },
3406         { 0x23, "SubscribeType" },
3407         /* New in WV-CSP 1.2 */
3408         { 0x24, "GetJoinedUsers-Request" },
3409         { 0x25, "GetJoinedUsers-Response" },
3410         { 0x26, "AdminMapList" },
3411         { 0x27, "AdminMapping" },
3412         { 0x28, "Mapping" },
3413         { 0x29, "ModMapping" },
3414         { 0x2A, "UserMapList" },
3415         { 0x2B, "UserMapping" },
3416
3417         { 0x00, NULL }
3418 };
3419
3420 /* Service negotiation code page - continued (0x08) */
3421 /* Same as cp8 of WV-CSP 1.1, but a new token is likely to be added. - XXX */
3422 static const value_string wbxml_wv_csp_12_tags_cp8[] = {
3423         /* 0x00 -- 0x04 GLOBAL */
3424         { 0x05, "MP" },
3425         { 0x06, "GETAUT" },
3426         { 0x07, "GETJU" },
3427
3428         { 0x00, NULL }
3429 };
3430
3431 /* Common code page - continued (0x09) */
3432 static const value_string wbxml_wv_csp_12_tags_cp9[] = {
3433         /* 0x00 -- 0x04 GLOBAL */
3434         { 0x05, "CIR" },
3435         { 0x06, "Domain" },
3436         { 0x07, "ExtBlock" },
3437         { 0x08, "HistoryPeriod" },
3438         { 0x09, "IDList" },
3439         { 0x0A, "MaxWatcherList" },
3440         { 0x0B, "ReactiveAuthState" },
3441         { 0x0C, "ReactiveAuthStatus" },
3442         { 0x0D, "ReactiveAuthStatusList" },
3443         { 0x0E, "Watcher" },
3444         { 0x0C, "WatcherStatus" }, /* Duplicate --> Will move to 0x0F? */
3445
3446         { 0x00, NULL }
3447 };
3448
3449 /* Access code page - continued (0x0A) */
3450 static const value_string wbxml_wv_csp_12_tags_cp10[] = {
3451         /* 0x00 -- 0x04 GLOBAL */
3452         { 0x05, "WV-CSP-NSDiscovery-Request" },
3453         { 0x06, "WV-CSP-NSDiscovery-Response" },
3454
3455         { 0x00, NULL }
3456 };
3457
3458 /*****    Attribute Start tokens   *****/
3459 /* Common code page (0x00) */
3460 static const value_string wbxml_wv_csp_12_attrStart_cp0[] = {
3461         /* 0x00 -- 0x04 GLOBAL */
3462         { 0x05, "xmlns='http://www.wireless-village.org/CSP'" },
3463         { 0x06, "xmlns='http://www.wireless-village.org/PA'" },
3464         { 0x07, "xmlns='http://www.wireless-village.org/TRC'" },
3465         /* New in WV-CSP 1.2 */
3466         { 0x08, "xmlns='http://www.openmobilealliance.org/DTD/WV-CSP'" },
3467         { 0x09, "xmlns='http://www.openmobilealliance.org/DTD/WV-PA'" },
3468         { 0x0A, "xmlns http://www.openmobilealliance.org/DTD/WV-TRC'" },
3469
3470         { 0x00, NULL }
3471 };
3472
3473 /*****    Attribute Value tokens   *****/
3474 /*
3475  * Element value tokens
3476  *
3477  * NOTE - WV-CSP uses the EXT_T_0 token in a peculiar way: the mb_u_int32
3478  * does *not* reference an offset in the string table, but it refers to
3479  * the index in the following value_string.
3480  *
3481  * Please note that:
3482  *  - Values 'T' and 'F' are Boolean values representing "True" and "False"
3483  *    (or "Yes" and "No" in some circumstances) respectively.
3484  *  - Values 'GR', 'IM', 'PR', 'SC', 'GM' and 'US' are enumerated values
3485  *    representing "Group", "Instant Messaging", "Presence", "Shared Content",
3486  *    "Group membership" and "User" respectively.
3487  *  - Values 'G', 'S' and 'U' are enumerated values representing "Get", "Set"
3488  *    and "Unset" respectively.
3489  *  - Values 'N' and 'P' are enumerated values representing "Notify/Get" and
3490  *    "Push" respectively.
3491  *
3492  * I repeat: this is NOT a attrValue[] array hence it is not called
3493  * wbxml_wv_XXX but vals_wv_XXX.
3494  */
3495 static const value_string vals_wv_csp_12_element_value_tokens[] = {
3496         /*
3497          * Common value tokens
3498          */
3499         { 0x00, "AccessType" },
3500         { 0x01, "ActiveUsers" },
3501         { 0x02, "Admin" },
3502         { 0x03, "application/" },
3503         { 0x04, "application/vnd.wap.mms-message" },
3504         { 0x05, "application/x-sms" },
3505         { 0x06, "AutoJoin" },
3506         { 0x07, "BASE64" },
3507         { 0x08, "Closed" },
3508         { 0x09, "Default" },
3509         { 0x0A, "DisplayName" },
3510         { 0x0B, "F" },
3511         { 0x0C, "G" },
3512         { 0x0D, "GR" },
3513         { 0x0E, "http://" },
3514         { 0x0F, "https://" },
3515         { 0x10, "image/" },
3516         { 0x11, "Inband" },
3517         { 0x12, "IM" },
3518         { 0x13, "MaxActiveUsers" },
3519         { 0x14, "Mod" },
3520         { 0x15, "Name" },
3521         { 0x16, "None" },
3522         { 0x17, "N" },
3523         { 0x18, "Open" },
3524         { 0x19, "Outband" },
3525         { 0x1A, "PR" },
3526         { 0x1B, "Private" },
3527         { 0x1C, "PrivateMessaging" },
3528         { 0x1D, "PrivilegeLevel" },
3529         { 0x1E, "Public" },
3530         { 0x1F, "P" },
3531         { 0x20, "Request" },
3532         { 0x21, "Response" },
3533         { 0x22, "Restricted" },
3534         { 0x23, "ScreenName" },
3535         { 0x24, "Searchable" },
3536         { 0x25, "S" },
3537         { 0x26, "SC" },
3538         { 0x27, "text/" },
3539         { 0x28, "text/plain" },
3540         { 0x29, "text/x-vCalendar" },
3541         { 0x2A, "text/x-vCard" },
3542         { 0x2B, "Topic" },
3543         { 0x2C, "T" },
3544         { 0x2D, "Type" },
3545         { 0x2E, "U" },
3546         { 0x2F, "US" },
3547         { 0x30, "www.wireless-village.org" },
3548         /* New in WV-CSP 1.2 */
3549         { 0x31, "AutoDelete" },
3550         { 0x32, "GM" },
3551         { 0x33, "Validity" },
3552         { 0x34, "DENIED" }, /* Duplicate */
3553         { 0x34, "ShowID" }, /* Duplicate */
3554         { 0x35, "GRANTED" },
3555         { 0x36, "PENDING" },
3556         /*
3557          * Access value tokens
3558          */
3559         { 0x3D, "GROUP_ID" },
3560         { 0x3E, "GROUP_NAME" },
3561         { 0x3F, "GROUP_TOPIC" },
3562         { 0x40, "GROUP_USER_ID_JOINED" },
3563         { 0x41, "GROUP_USER_ID_OWNER" },
3564         { 0x42, "HTTP" },
3565         { 0x43, "SMS" },
3566         { 0x44, "STCP" },
3567         { 0x45, "SUDP" },
3568         { 0x46, "USER_ALIAS" },
3569         { 0x47, "USER_EMAIL_ADDRESS" },
3570         { 0x48, "USER_FIRST_NAME" },
3571         { 0x49, "USER_ID" },
3572         { 0x4A, "USER_LAST_NAME" },
3573         { 0x4B, "USER_MOBILE_NUMBER" },
3574         { 0x4C, "USER_ONLINE_STATUS" },
3575         { 0x4D, "WAPSMS" },
3576         { 0x4E, "WAPUDP" },
3577         { 0x4F, "WSP" },
3578         /* New in WV-CSP 1.2 */
3579         { 0x50, "GROUP_USER_ID_AUTOJOIN" },
3580         /*
3581          * Presence value tokens
3582          */
3583         { 0x5B, "ANGRY" },
3584         { 0x5C, "ANXIOUS" },
3585         { 0x5D, "ASHAMED" },
3586         { 0x5E, "AUDIO_CALL" },
3587         { 0x5F, "AVAILABLE" },
3588         { 0x60, "BORED" },
3589         { 0x61, "CALL" },
3590         { 0x62, "CLI" },
3591         { 0x63, "COMPUTER" },
3592         { 0x64, "DISCREET" },
3593         { 0x65, "EMAIL" },
3594         { 0x66, "EXCITED" },
3595         { 0x67, "HAPPY" },
3596         { 0x68, "IM" },
3597         { 0x69, "IM_OFFLINE" },
3598         { 0x6A, "IM_ONLINE" },
3599         { 0x6B, "IN_LOVE" },
3600         { 0x6C, "INVINCIBLE" },
3601         { 0x6D, "JEALOUS" },
3602         { 0x6E, "MMS" },
3603         { 0x6F, "MOBILE_PHONE" },
3604         { 0x70, "NOT_AVAILABLE" },
3605         { 0x71, "OTHER" },
3606         { 0x72, "PDA" },
3607         { 0x73, "SAD" },
3608         { 0x74, "SLEEPY" },
3609         { 0x75, "SMS" },
3610         { 0x76, "VIDEO_CALL" },
3611         { 0x77, "VIDEO_STREAM" },
3612
3613         { 0x00, NULL }
3614 };
3615
3616
3617
3618 /***** Token code page aggregation *****/
3619
3620 static char *
3621 ext_t_0_wv_cspc_12(tvbuff_t *tvb _U_, guint32 value, guint32 str_tbl _U_)
3622 {
3623     char *str = g_strdup_printf("Common Value: '%s'",
3624             val_to_str(value, vals_wv_csp_12_element_value_tokens,
3625                 "<Unknown WV-CSP 1.2 Common Value token 0x%X>"));
3626     return str;
3627 }
3628
3629 #define wbxml_wv_csp_12_global wbxml_wv_csp_11_global
3630
3631 static const value_valuestring wbxml_wv_csp_12_tags[] = {
3632         {  0, wbxml_wv_csp_12_tags_cp0 },
3633         {  1, wbxml_wv_csp_12_tags_cp1 },
3634         {  2, wbxml_wv_csp_12_tags_cp2 },
3635         {  3, wbxml_wv_csp_12_tags_cp3 },
3636         {  4, wbxml_wv_csp_12_tags_cp4 },
3637         {  5, wbxml_wv_csp_12_tags_cp5 },
3638         {  6, wbxml_wv_csp_12_tags_cp6 },
3639         {  7, wbxml_wv_csp_12_tags_cp7 },
3640         {  8, wbxml_wv_csp_12_tags_cp8 },
3641         {  9, wbxml_wv_csp_12_tags_cp9 },
3642         { 10, wbxml_wv_csp_12_tags_cp10 },
3643         {  0, NULL }
3644 };
3645
3646 static const value_valuestring wbxml_wv_csp_12_attrStart[] = {
3647         { 0, wbxml_wv_csp_12_attrStart_cp0 },
3648         { 0, NULL }
3649 };
3650
3651 static const wbxml_decoding decode_wv_cspc_12 = {
3652     "Wireless-Village Client-Server Protocol 1.2",
3653     "WV-CSP 1.2",
3654     { ext_t_0_wv_cspc_12, NULL, NULL },
3655     wbxml_wv_csp_12_global,
3656     wbxml_wv_csp_12_tags,
3657     wbxml_wv_csp_12_attrStart,
3658     NULL
3659 };
3660 #endif /* Remove_this_comment_when_WV_CSP_will_be_an_approved_spec */
3661
3662
3663
3664
3665
3666 /********************** WBXML token mapping aggregation **********************/
3667
3668 static const wbxml_decoding *get_wbxml_decoding_from_public_id (guint32 publicid);
3669 static const wbxml_decoding *get_wbxml_decoding_from_content_type (
3670         const char *content_type);
3671
3672
3673 /**
3674  ** Aggregation of content type and aggregated code pages
3675  ** Content type map lookup will stop at the 1st entry with 3rd member = FALSE
3676  **/
3677
3678 /*
3679  * The following map contains entries registered with a registered WBXML
3680  * public ID. See WAP WINA or OMA OMNA for registered values:
3681  * http://www.openmobilealliance.org/tech/omna/ */
3682 static const wbxml_integer_list well_known_public_id_list[] = {
3683     /* 0x00 - Unknown or missing Public ID */
3684     /* 0x01 - LITERAL PublicID - see String Table */
3685     { 0x02,     &decode_wmlc_10 },      /* WML 1.0 */
3686     /* 0x03 - WTA 1.0 */
3687     { 0x04,     &decode_wmlc_11 },      /* WML 1.1 */
3688     { 0x05,     &decode_sic_10 },       /* SI 1.0 */
3689     { 0x06,     &decode_slc_10 },       /* SL 1.0 */
3690     { 0x07,     &decode_coc_10 },       /* CO 1.0 */
3691     { 0x08,     &decode_channelc_10 },  /* CHANNEL 1.0 */
3692     { 0x09,     &decode_wmlc_12 },      /* WML 1.2 */
3693     { 0x0A,     &decode_wmlc_13 },      /* WML 1.3 */
3694     { 0x0B,     &decode_provc_10 },     /* PROV 1.0 */
3695     /* 0x0C - WTA-WML 1.2 */
3696     { 0x0D,     &decode_emnc_10 },      /* EMN 1.0 */
3697     /* 0x0E - DRMREL 1.0 */
3698     { 0x0F,     &decode_wv_cspc_10 },   /* WV-CSP 1.0 */
3699     { 0x10,     &decode_wv_cspc_11 },   /* WV-CSP 1.1 */
3700
3701     { 0x020B,   &decode_nokiaprovc_70 },/* Nokia OTA Provisioning 7.0 */
3702     { 0x0FD1,   &decode_syncmlc_10 },   /* SyncML 1.0 */
3703     { 0x0FD3,   &decode_syncmlc_11 },   /* SyncML 1.1 */
3704     /* Note: I assumed WML+ 1.x would be not that different from WML 1.x,
3705      *       the real mapping should come from Phone.com (OpenWave)! */
3706     { 0x1108,   &decode_wmlc_11 },      /* Phone.com WMLC+ 1.1 - not 100% correct */
3707     { 0x110D,   &decode_wmlc_13 },      /* Phone.com WMLC+ 1.3 - not 100% correct */
3708
3709     { 0x00,     NULL }
3710 };
3711
3712 /* The following map contains entries only registered with a literal media
3713  * type. */
3714 static const wbxml_literal_list content_type_list[] = {
3715     {   "application/x-wap-prov.browser-settings",
3716         NULL,
3717         &decode_nokiaprovc_70
3718     },
3719     {   "application/x-wap-prov.browser-bookmarks",
3720         NULL,
3721         &decode_nokiaprovc_70
3722     },
3723     {   "application/vnd.wv.csp.wbxml",
3724         NULL,
3725         &decode_wv_cspc_11
3726     },
3727     {   NULL, NULL, NULL }
3728 };
3729         
3730
3731 /* Returns a pointer to the WBXML token map for the given WBXML public
3732  * identifier value (see WINA for a table with defined identifiers). */
3733 static const wbxml_decoding *get_wbxml_decoding_from_public_id (guint32 public_id)
3734 {
3735     const wbxml_decoding *map = NULL;
3736
3737     DebugLog(("get_wbxml_decoding_from_public_id: public_id = %u\n",
3738                 public_id));
3739     if (public_id >= 2) {
3740         const wbxml_integer_list *item = well_known_public_id_list;
3741
3742         while (item && item->public_id && item->map) {
3743             if (item->public_id == public_id) {
3744                 map = item->map;
3745                 break;
3746             }
3747             item++;
3748         }
3749     }
3750     return map;
3751 }
3752
3753 static const wbxml_decoding *get_wbxml_decoding_from_content_type (
3754         const char *content_type)
3755 {
3756     const wbxml_decoding *map = NULL;
3757
3758     DebugLog(("get_wbxml_decoding_from_content_type: content_type = [%s]\n",
3759                 content_type));
3760     if (content_type && content_type[0]) {
3761         const wbxml_literal_list *item = content_type_list;
3762
3763         while (item && item->content_type) {
3764             if (strcasecmp(content_type, item->content_type) == 0) {
3765                 map = item->map;
3766                 break;
3767             }
3768             item++;
3769         }
3770     }
3771     return map;
3772 }
3773
3774
3775 /* WBXML content token mapping depends on the following parameters:
3776  *   - Content type (guint32)
3777  *   - Token type (global, tags, attrStart, attrValue)
3778  *   - Code page for tag and attribute
3779  *
3780  * This results in the following steps:
3781  *   1. Retrieve content type mapping
3782  *   2. If exists, retrieve token type mapping
3783  *   3. If exists, retrieve required code page
3784  *   4. If exists, retrieve token mapping
3785  */
3786
3787 #define wbxml_UNDEFINED_TOKEN \
3788         "(Requested token not defined for this content type)"
3789 #define wbxml_UNDEFINED_TOKEN_CODE_PAGE \
3790         "(Requested token code page not defined for this content type)"
3791 #define wbxml_UNDEFINED_TOKEN_MAP \
3792         "(Requested token map not defined for this content type)"
3793 /* Return token mapping for a given content mapping entry. */
3794 static const char *
3795 map_token (const value_valuestring *token_map, guint8 codepage, guint8 token) {
3796         const value_string *vs;
3797         const char *s;
3798
3799         if (token_map) { /* Found map */
3800                 if ((vs = val_to_valstr (codepage, token_map))) {
3801                         /* Found codepage map */
3802                         s = match_strval (token, vs);
3803                         if (s) { /* Found valid token */
3804                                 DebugLog(("map_token(codepage = %u, token = %u: [%s]\n", codepage, token, s));
3805                                 return s;
3806                         }
3807                         /* No valid token mapping in specified code page of token map */
3808                         DebugLog(("map_token(codepage = %u, token = %u: "
3809                                                 wbxml_UNDEFINED_TOKEN "\n", codepage, token));
3810                         return wbxml_UNDEFINED_TOKEN;
3811                 }
3812                 /* There is no token map entry for the requested code page */
3813                 DebugLog(("map_token(codepage = %u, token = %u: "
3814                                         wbxml_UNDEFINED_TOKEN_CODE_PAGE "\n", codepage, token));
3815                 return wbxml_UNDEFINED_TOKEN_CODE_PAGE;
3816         }
3817         /* The token map does not exist */
3818         DebugLog(("map_token(codepage = %u, token = %u: "
3819                                 wbxml_UNDEFINED_TOKEN_MAP "\n", codepage, token));
3820         return wbxml_UNDEFINED_TOKEN_MAP;
3821 }
3822
3823
3824
3825
3826
3827 /************************** Function prototypes **************************/
3828
3829
3830 static void
3831 dissect_wbxml(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
3832
3833 void
3834 proto_register_wbxml(void);
3835
3836 /* Parse and display the WBXML string table */
3837 static void
3838 show_wbxml_string_table (proto_tree *tree, tvbuff_t *tvb, guint32 str_tbl,
3839                 guint32 str_tbl_len);
3840
3841 /* Parse data while in STAG state */
3842 static guint32
3843 parse_wbxml_tag (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
3844                 guint32 str_tbl, guint8 *level, guint8 *codepage_stag, guint8 *codepage_attr);
3845
3846 /* Parse data while in STAG state;
3847  * interpret tokens as defined by content type */
3848 static guint32
3849 parse_wbxml_tag_defined (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
3850                 guint32 str_tbl, guint8 *level, guint8 *codepage_stag, guint8 *codepage_attr,
3851                 const wbxml_decoding *map);
3852
3853 /* Parse data while in ATTR state */
3854 static guint32
3855 parse_wbxml_attribute_list (proto_tree *tree, tvbuff_t *tvb,
3856                 guint32 offset, guint32 str_tbl, guint8 level, guint8 *codepage_attr);
3857
3858 /* Parse data while in ATTR state;
3859  * interpret tokens as defined by content type */
3860 static guint32
3861 parse_wbxml_attribute_list_defined (proto_tree *tree, tvbuff_t *tvb,
3862                 guint32 offset, guint32 str_tbl, guint8 level, guint8 *codepage_attr,
3863                 const wbxml_decoding *map);
3864
3865
3866 /****************** WBXML protocol dissection functions ******************/
3867
3868
3869 /* Code to actually dissect the packets */
3870 static void
3871 dissect_wbxml(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3872 {
3873         /* Set up structures needed to add the protocol subtree and manage it */
3874         proto_item *ti;
3875         proto_tree *wbxml_tree; /* Main WBXML tree */
3876         proto_tree *wbxml_str_tbl_tree; /* String table subtree */
3877         proto_tree *wbxml_content_tree; /* Content subtree */
3878         guint8 version;
3879         guint offset = 0;
3880         guint32 len;
3881         guint32 charset = 0;
3882         guint32 charset_len = 0;
3883         guint32 publicid;
3884         guint32 publicid_index = 0;
3885         guint32 publicid_len;
3886         guint32 str_tbl;
3887         guint32 str_tbl_len;
3888         guint32 str_tbl_len_len = 0;
3889         guint8 level = 0; /* WBXML recursion level */
3890         const wbxml_decoding *content_map = NULL;
3891         gchar *summary = NULL;
3892         guint8 codepage_stag = 0;
3893         guint8 codepage_attr = 0;
3894
3895         DebugLog(("dissect_wbxml: Dissecting packet %u\n", pinfo->fd->num));
3896         /* WBXML format
3897          * 
3898          * Version 1.0: version publicid         strtbl BODY
3899          * Version 1.x: version publicid charset strtbl BODY
3900          *
3901          * Last valid format: WBXML 1.3
3902          */
3903         switch ( version = tvb_get_guint8 (tvb, 0) ) {
3904                 case 0x00: /* WBXML/1.0 */
3905                         break;
3906
3907                 case 0x01: /* WBXML/1.1 */
3908                 case 0x02: /* WBXML/1.2 */
3909                 case 0x03: /* WBXML/1.3 */
3910                         break;
3911
3912                 default:
3913                         return;
3914         }
3915
3916         /* In order to properly construct the packet summary,
3917          * I need to read the entire WBXML header
3918          * up to the string table length.
3919          */
3920
3921         /* Public ID */
3922         publicid = tvb_get_guintvar(tvb, 1, &publicid_len);
3923         if (! publicid) {
3924                 /* Public identifier in string table */
3925                 publicid_index = tvb_get_guintvar (tvb, 1+publicid_len, &len);
3926                 publicid_len += len;
3927         }
3928         offset = 1 + publicid_len;
3929
3930         /* Version-specific handling of Charset */
3931         switch ( version ) {
3932                 case 0x00: /* WBXML/1.0 */
3933                         /* No charset */
3934                         break;
3935
3936                 case 0x01: /* WBXML/1.1 */
3937                 case 0x02: /* WBXML/1.2 */
3938                 case 0x03: /* WBXML/1.3 */
3939                         /* Get charset */
3940                         charset = tvb_get_guintvar (tvb, offset, &charset_len);
3941                         offset += charset_len;
3942                         break;
3943
3944                 default: /* Impossible since we returned already earlier */
3945                         g_error("%s:%u: WBXML version octet 0x%02X only partly supported!\n"
3946                                         "Please report this as a bug.\n", __FILE__, __LINE__, version);
3947                         g_assert_not_reached();
3948                         break;
3949         }
3950
3951         /* String table: read string table length in bytes */
3952         str_tbl_len = tvb_get_guintvar (tvb, offset, &str_tbl_len_len);
3953         str_tbl = offset + str_tbl_len_len; /* Start of 1st string in string table */
3954
3955         /* Compose the summary line */
3956         if ( publicid ) {
3957                 summary = g_strdup_printf("%s, Public ID: \"%s\"",
3958                                 match_strval (version, vals_wbxml_versions),
3959                                 match_strval (publicid, vals_wbxml_public_ids));
3960         } else {
3961                 /* Read length of Public ID from string table */
3962                 len = tvb_strsize (tvb, str_tbl + publicid_index);
3963                 summary = g_strdup_printf("%s, Public ID: \"%s\"",
3964                                 match_strval (version, vals_wbxml_versions),
3965                                 tvb_format_text (tvb, str_tbl + publicid_index, len - 1));
3966         }
3967
3968         /* Add summary to INFO column if it is enabled */
3969         if (check_col(pinfo->cinfo, COL_INFO))
3970                 col_append_fstr(pinfo->cinfo, COL_INFO, " (WBXML %s)", summary);
3971
3972         /* create display subtree for the protocol */
3973         ti = proto_tree_add_item (tree, proto_wbxml, tvb, 0, -1, FALSE);
3974         proto_item_append_text(ti, ", Version: %s", summary);
3975         g_free(summary);
3976         /*
3977          * Now show the protocol subtree, if tree is set.
3978          */
3979         if ( tree ) {
3980                 wbxml_tree = proto_item_add_subtree(ti, ett_wbxml);
3981
3982                 /* WBXML Version */
3983                 proto_tree_add_uint (wbxml_tree, hf_wbxml_version,
3984                                 tvb, 0, 1, version);
3985
3986                 /* Public ID */
3987                 if (publicid) { /* Known Public ID */
3988                         proto_tree_add_uint(wbxml_tree, hf_wbxml_public_id_known,
3989                                         tvb, 1, publicid_len, publicid);
3990                 } else { /* Public identifier in string table */
3991                         proto_tree_add_item (wbxml_tree, hf_wbxml_public_id_literal,
3992                                         tvb, 1, publicid_len, FALSE);
3993                 }
3994                 offset = 1 + publicid_len;
3995
3996                 if ( version ) { /* Charset */
3997                         proto_tree_add_uint (wbxml_tree, hf_wbxml_charset,
3998                                         tvb, 1 + publicid_len, charset_len, charset);
3999                         offset += charset_len;
4000                 }
4001
4002                 str_tbl_len = tvb_get_guintvar (tvb, offset, &len);
4003                 str_tbl = offset + len; /* Start of 1st string in string table */
4004
4005                 /* String Table */
4006                 ti = proto_tree_add_text(wbxml_tree,
4007                                 tvb, offset, len + str_tbl_len, "String table: %u bytes",
4008                                 str_tbl_len);
4009
4010                 if (wbxml_tree && str_tbl_len) { /* Display string table as subtree */
4011                         wbxml_str_tbl_tree = proto_item_add_subtree (ti,
4012                                         ett_wbxml_str_tbl);
4013                         show_wbxml_string_table (wbxml_str_tbl_tree, tvb,
4014                                         str_tbl, str_tbl_len);
4015                 }
4016
4017                 /* Data starts HERE */
4018                 offset += len + str_tbl_len;
4019
4020                 /* The WBXML BODY starts here */
4021                 ti = proto_tree_add_text (wbxml_tree, tvb, offset, -1,
4022                                 "Data representation");
4023                 wbxml_content_tree = proto_item_add_subtree (ti, ett_wbxml_content);
4024
4025                 /* The parse_wbxml_X() functions will process the content correctly,
4026                  * irrespective of the WBXML version used. For the WBXML body, this
4027                  * means that there is a different processing for the global token
4028                  * RESERVED_2 (WBXML 1.0) or OPAQUE (WBXML 1.x with x > 0).  */
4029                 if (wbxml_tree) { /* Show only if visible */
4030                     /* Retrieve the content token mapping if available */
4031                     content_map = get_wbxml_decoding_from_public_id (publicid);
4032                     if (! content_map) {
4033                         content_map = get_wbxml_decoding_from_content_type (pinfo->match_string);
4034                         if (! content_map) {
4035                             proto_tree_add_text (wbxml_content_tree, tvb,
4036                                     offset, -1,
4037                                     "[Rendering of this content type"
4038                                     " not (yet) supported]");
4039                         } else {
4040                             proto_item_append_text(ti,
4041                                     " is based on Content-Type: %s (chosen decoding: %s)",
4042                                     pinfo->match_string, content_map->name);
4043                         }
4044                     }
4045                     proto_tree_add_text (wbxml_content_tree, tvb,
4046                             offset, -1,
4047                             "Level | State | Codepage "
4048                             "| WBXML Token Description         "
4049                             "| Rendering");
4050                     if (content_map) {
4051                         len = parse_wbxml_tag_defined (wbxml_content_tree,
4052                                 tvb, offset, str_tbl, &level, &codepage_stag,
4053                                 &codepage_attr, content_map);
4054                     } else {
4055                         /* Default: WBXML only, no interpretation of the content */
4056                         len = parse_wbxml_tag (wbxml_content_tree, tvb, offset,
4057                                 str_tbl, &level, &codepage_stag, &codepage_attr);
4058                     }
4059                 }
4060                 return;
4061         }
4062 }
4063
4064
4065 /* Parse and display the WBXML string table (in a 3-column table format).
4066  * This function displays:
4067  *  - the offset in the string table,
4068  *  - the length of the string
4069  *  - the string.
4070  */
4071 static void
4072 show_wbxml_string_table (proto_tree *tree, tvbuff_t *tvb, guint32 str_tbl,
4073                 guint32 str_tbl_len)
4074 {
4075         guint32 off = str_tbl;
4076         guint32 len = 0;
4077         guint32 end = str_tbl + str_tbl_len;
4078
4079         proto_tree_add_text (tree, tvb, off, end,
4080                         "Start  | Length | String");
4081         while (off < end) {
4082                 len = tvb_strsize (tvb, off);
4083                 proto_tree_add_text (tree, tvb, off, len,
4084                                 "%6d | %6d | '%s'",
4085                                 off - str_tbl, len,
4086                                 tvb_format_text (tvb, off, len-1));
4087                 off += len;
4088         }
4089 }
4090
4091
4092 /* Indentation code is based on a static const array of space characters.
4093  * At least one single space is returned */
4094 static const char indent_buffer[514] = " "
4095         "                                                                "
4096         "                                                                "
4097         "                                                                "
4098         "                                                                "
4099         "                                                                "
4100         "                                                                "
4101         "                                                                "
4102         "                                                                "
4103         ; /* Generate XML indentation (length = 1 + 2 * 256 + 1 for '\0') */
4104
4105 static const char * Indent (guint8 level) {
4106         return indent_buffer + (512 - 2 * (level));
4107 }
4108
4109
4110 /********************
4111  * WBXML tag tokens *
4112  ********************
4113  * 
4114  * Bit Mask  : Example
4115  * -------------------
4116  * 00.. .... : <tag />
4117  *
4118  * 01.. .... : <tag>
4119  *               CONTENT
4120  *             </tag>
4121  *
4122  * 10.. .... : <tag
4123  *               atrtribute1="value1"
4124  *               atrtribute2="value2"
4125  *             />
4126  * 
4127  * 11.. .... : <tag
4128  *               atrtribute1="value1"
4129  *               atrtribute2="value2"
4130  *             >
4131  *               CONTENT
4132  *             </tag>
4133  *
4134  * NOTES
4135  *   - An XML PI is parsed as an attribute list (same syntax).
4136  *   - A code page switch only applies to the single token that follows.
4137  */
4138
4139
4140 /* This function parses the WBXML and maps known token interpretations
4141  * to the WBXML tokens. As a result, the original XML document can be
4142  * recreated. Indentation is generated in order to ease reading.
4143  *
4144  * Attribute parsing is done in parse_wbxml_attribute_list_defined().
4145  *
4146  * The wbxml_decoding entry *map contains the actual token mapping.
4147  *
4148  * NOTE: In order to parse the content, some recursion is required.
4149  *       However, for performance reasons, recursion has been avoided
4150  *       where possible (tags without content within tags with content).
4151  *       This is achieved by means of the parsing_tag_content and tag_save*
4152  *       variables.
4153  *
4154  * NOTE: See above for known token mappings.
4155  *
4156  * NOTE: As tags can be opened and closed, a tag representation lookup
4157  *       may happen once or twice for a given tag. For efficiency reasons,
4158  *       the literal tag value is stored and used throughout the code.
4159  *       With the introduction of code page support, this solution is robust
4160  *       as the lookup only occurs once, removing the need for storage of
4161  *       the used code page.
4162  */
4163 static guint32
4164 parse_wbxml_tag_defined (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
4165                 guint32 str_tbl, guint8 *level, guint8 *codepage_stag, guint8 *codepage_attr,
4166                 const wbxml_decoding *map)
4167 {
4168         guint32 tvb_len = tvb_reported_length (tvb);
4169         guint32 off = offset;
4170         guint32 len;
4171         guint str_len;
4172         guint32 ent;
4173         guint32 index;
4174         guint8 peek;
4175         guint32 tag_len; /* Length of the index (uintvar) from a LITERAL tag */
4176         guint8 tag_save_known = 0; /* Will contain peek & 0x3F (tag identity) */
4177         guint8 tag_new_known = 0; /* Will contain peek & 0x3F (tag identity) */
4178         const char *tag_save_literal; /* Will contain the LITERAL tag identity */
4179         const char *tag_new_literal; /* Will contain the LITERAL tag identity */
4180         guint8 parsing_tag_content = FALSE; /* Are we parsing content from a
4181                                                                                    tag with content: <x>Content</x>
4182                                                                                    
4183                                                                                    The initial state is FALSE.
4184                                                                                    This state will trigger recursion. */
4185         tag_save_literal = NULL; /* Prevents compiler warning */
4186
4187         DebugLog(("parse_wbxml_tag_defined (level = %u, offset = %u)\n", *level, offset));
4188         while (off < tvb_len) {
4189                 peek = tvb_get_guint8 (tvb, off);
4190                 DebugLog(("STAG: (top of while) level = %3u, peek = 0x%02X, off = %u, tvb_len = %u\n", *level, peek, off, tvb_len));
4191                 if ((peek & 0x3F) < 4) switch (peek) { /* Global tokens in state = STAG
4192                                                                                                   but not the LITERAL tokens */
4193                         case 0x00: /* SWITCH_PAGE */
4194                                 *codepage_stag = tvb_get_guint8 (tvb, off+1);
4195                                 proto_tree_add_text (tree, tvb, off, 2,
4196                                                 "      | Tag   | T -->%3d "
4197                                                 "| SWITCH_PAGE (Tag code page)     "
4198                                                 "|",
4199                                                 *codepage_stag);
4200                                 off += 2;
4201                                 break;
4202                         case 0x01: /* END: only possible for Tag with Content */
4203                                 if (tag_save_known) { /* Known TAG */
4204                                         proto_tree_add_text (tree, tvb, off, 1,
4205                                                         "  %3d | Tag   | T %3d    "
4206                                                         "| END (Known Tag 0x%02X)            "
4207                                                         "| %s</%s>",
4208                                                         *level, *codepage_stag,
4209                                                         tag_save_known, Indent (*level),
4210                                                         tag_save_literal); /* We already looked it up! */
4211                                 } else { /* Literal TAG */
4212                                         proto_tree_add_text (tree, tvb, off, 1,
4213                                                         "  %3d | Tag   | T %3d    "
4214                                                         "| END (Literal Tag)               "
4215                                                         "| %s</%s>",
4216                                                         *level, *codepage_stag, Indent (*level),
4217                                                         tag_save_literal);
4218                                 }
4219                                 (*level)--;
4220                                 off++;
4221                                 /* Reset code page: not needed as return from recursion */
4222                                 DebugLog(("STAG: level = %u, Return: len = %u\n", *level, off - offset));
4223                                 return (off - offset);
4224                                 break;
4225                         case 0x02: /* ENTITY */
4226                                 ent = tvb_get_guintvar (tvb, off+1, &len);
4227                                 proto_tree_add_text (tree, tvb, off, 1+len,
4228                                                 "  %3d | Tag   | T %3d    "
4229                                                 "| ENTITY                          "
4230                                                 "| %s'&#%u;'",
4231                                                 *level, *codepage_stag, Indent (*level), ent);
4232                                 off += 1+len;
4233                                 break;
4234                         case 0x03: /* STR_I */
4235                                 len = tvb_strsize (tvb, off+1);
4236                                 proto_tree_add_text (tree, tvb, off, 1+len,
4237                                                 "  %3d | Tag   | T %3d    "
4238                                                 "| STR_I (Inline string)           "
4239                                                 "| %s\'%s\'",
4240                                                 *level, *codepage_stag, Indent(*level),
4241                                                 tvb_format_text (tvb, off+1, len-1));
4242                                 off += 1+len;
4243                                 break;
4244                         case 0x40: /* EXT_I_0 */
4245                         case 0x41: /* EXT_I_1 */
4246                         case 0x42: /* EXT_I_2 */
4247                                 /* Extension tokens */
4248                                 len = tvb_strsize (tvb, off+1);
4249                                 proto_tree_add_text (tree, tvb, off, 1+len,
4250                                                 "  %3d | Tag   | T %3d    "
4251                                                 "| EXT_I_%1x    (Extension Token)    "
4252                                                 "| %s(%s: \'%s\')",
4253                                                 *level, *codepage_stag,
4254                                                 peek & 0x0f, Indent (*level),
4255                                                 map_token (map->global, 0, peek),
4256                                                 tvb_format_text (tvb, off+1, len-1));
4257                                 off += 1+len;
4258                                 break;
4259                         case 0x43: /* PI */
4260                                 proto_tree_add_text (tree, tvb, off, 1,
4261                                                 "  %3d | Tag   | T %3d    "
4262                                                 "| PI (XML Processing Instruction) "
4263                                                 "| %s<?xml",
4264                                                 *level, *codepage_stag, Indent (*level));
4265                                 len = parse_wbxml_attribute_list_defined (tree, tvb, off,
4266                                                 str_tbl, *level, codepage_attr, map);
4267                                 /* Check that there is still room in packet */
4268                                 off += len;
4269                                 if (off >= tvb_len) {
4270                                         DebugLog(("STAG: level = %u, ThrowException: len = %u (short frame)\n", *level, off - offset));
4271                                         /*
4272                                          * TODO - Do we need to free g_malloc()ed memory?
4273                                          */
4274                                         THROW(ReportedBoundsError);
4275                                 }
4276                                 proto_tree_add_text (tree, tvb, off-1, 1,
4277                                                 "  %3d | Tag   | T %3d    "
4278                                                 "| END (PI)                        "
4279                                                 "| %s?>",
4280                                                 *level, *codepage_stag, Indent (*level));
4281                                 break;
4282                         case 0x80: /* EXT_T_0 */
4283                         case 0x81: /* EXT_T_1 */
4284                         case 0x82: /* EXT_T_2 */
4285                                 /* Extension tokens */
4286                                 index = tvb_get_guintvar (tvb, off+1, &len);
4287                                 str_len = tvb_strsize (tvb, str_tbl+index);
4288                                 {   char *s;
4289                                     if (map->ext_t[peek & 0x03])
4290                                         s = (map->ext_t[peek & 0x03])(tvb, index, str_tbl);
4291                                     else
4292                                         s = g_strdup_printf("EXT_T_%1x (%s)", peek & 0x03, 
4293                                                 map_token (map->global, 0, peek));
4294                                     proto_tree_add_text (tree, tvb, off, 1+len,
4295                                                 "  %3d | Tag   | T %3d    "
4296                                                 "| EXT_T_%1x    (Extension Token)    "
4297                                                 "| %s%s",
4298                                                 *level, *codepage_stag, peek & 0x0f, Indent (*level),
4299                                                 s);
4300                                     g_free(s);
4301                                 }
4302                                 off += 1+len;
4303                                 break;
4304                         case 0x83: /* STR_T */
4305                                 index = tvb_get_guintvar (tvb, off+1, &len);
4306                                 str_len = tvb_strsize (tvb, str_tbl+index);
4307                                 proto_tree_add_text (tree, tvb, off, 1+len,
4308                                                 "  %3d | Tag   | T %3d    "
4309                                                 "| STR_T (Tableref string)         "
4310                                                 "| %s\'%s\'",
4311                                                 *level, *codepage_stag, Indent (*level),
4312                                                 tvb_format_text (tvb, str_tbl+index, str_len-1));
4313                                 off += 1+len;
4314                                 break;
4315                         case 0xC0: /* EXT_0 */
4316                         case 0xC1: /* EXT_1 */
4317                         case 0xC2: /* EXT_2 */
4318                                 /* Extension tokens */
4319                                 proto_tree_add_text (tree, tvb, off, 1,
4320                                                 "  %3d | Tag   | T %3d    "
4321                                                 "| EXT_%1x      (Extension Token)    "
4322                                                 "| %s(%s)",
4323                                                 *level, *codepage_stag, peek & 0x0f, Indent (*level),
4324                                                 map_token (map->global, 0, peek));
4325                                 off++;
4326                                 break;
4327                         case 0xC3: /* OPAQUE - WBXML 1.1 and newer */
4328                                 if (tvb_get_guint8 (tvb, 0)) { /* WBXML 1.x (x > 0) */
4329                                         index = tvb_get_guintvar (tvb, off+1, &len);
4330                                         proto_tree_add_text (tree, tvb, off, 1 + len + index,
4331                                                         "  %3d | Tag   | T %3d    "
4332                                                         "| OPAQUE (Opaque data)            "
4333                                                         "| %s(%d bytes of opaque data)",
4334                                                         *level, *codepage_stag, Indent (*level), index);
4335                                         off += 1+len+index;
4336                                 } else { /* WBXML 1.0 - RESERVED_2 token (invalid) */
4337                                         proto_tree_add_text (tree, tvb, off, 1,
4338                                                         "  %3d | Tag   | T %3d    "
4339                                                         "| RESERVED_2     (Invalid Token!) "
4340                                                         "| WBXML 1.0 parsing stops here.",
4341                                                         *level, *codepage_stag);
4342                                         /* Stop processing as it is impossible to parse now */
4343                                         off = tvb_len;
4344                                         DebugLog(("STAG: level = %u, Return: len = %u\n", *level, off - offset));
4345                                         return (off - offset);
4346                                 }
4347                                 break;
4348
4349                                 /* No default clause, as all cases have been treated */
4350                 } else { /* LITERAL or Known TAG */
4351                         /* We must store the initial tag, and also retrieve the new tag.
4352                          * For efficiency reasons, we store the literal tag representation
4353                          * for known tags too, so we can easily close the tag without the
4354                          * need of a new lookup and avoiding storage of token codepage.
4355                          * 
4356                          * There are 4 possibilities:
4357                          *
4358                          *  1. Known tag followed by a known tag
4359                          *  2. Known tag followed by a LITERAL tag
4360                          *  3. LITERAL tag followed by Known tag
4361                          *  4. LITERAL tag followed by LITERAL tag
4362                          */
4363
4364                         /* Store the new tag */
4365                         tag_len = 0;
4366                         if ((peek & 0x3F) == 4) { /* LITERAL */
4367                                 DebugLog(("STAG: LITERAL tag (peek = 0x%02X, off = %u) - TableRef follows!\n", peek, off));
4368                                 index = tvb_get_guintvar (tvb, off+1, &tag_len);
4369                                 str_len = tvb_strsize (tvb, str_tbl+index);
4370                                 tag_new_literal = tvb_get_ptr (tvb, str_tbl+index, str_len);
4371                                 tag_new_known = 0; /* invalidate known tag_new */
4372                         } else { /* Known tag */
4373                                 tag_new_known = peek & 0x3F;
4374                                 tag_new_literal = map_token (map->tags, *codepage_stag,
4375                                                                                 tag_new_known);
4376                                 /* Stored looked up tag name string */
4377                         }
4378
4379                         /* Parsing of TAG starts HERE */
4380                         if (peek & 0x40) { /* Content present */
4381                                 /* Content follows
4382                                  * [!] An explicit END token is expected in these cases!
4383                                  * ==> Recursion possible if we encounter a tag with content;
4384                                  *     recursion will return at the explicit END token.
4385                                  */
4386                                 if (parsing_tag_content) { /* Recurse */
4387                                         DebugLog(("STAG: Tag in Tag - RECURSE! (off = %u)\n", off));
4388                                         /* Do not process the attribute list:
4389                                          * recursion will take care of it */
4390                                         (*level)++;
4391                                         len = parse_wbxml_tag_defined (tree, tvb, off, str_tbl,
4392                                                         level, codepage_stag, codepage_attr, map);
4393                                         off += len;
4394                                 } else { /* Now we will have content to parse */
4395                                         /* Save the start tag so we can properly close it later. */
4396                                         if ((peek & 0x3F) == 4) { /* Literal tag */
4397                                                 tag_save_literal = tag_new_literal;
4398                                                 tag_save_known = 0;
4399                                         } else { /* Known tag */
4400                                                 tag_save_known = tag_new_known;
4401                                                 tag_save_literal = tag_new_literal;
4402                                                 /* The last statement avoids needless lookups */
4403                                         }
4404                                         /* Process the attribute list if present */
4405                                         if (peek & 0x80) { /* Content and Attribute list present */
4406                                                 if (tag_new_known) { /* Known tag */
4407                                                         proto_tree_add_text (tree, tvb, off, 1,
4408                                                                         "  %3d | Tag   | T %3d    "
4409                                                                         "|   Known Tag 0x%02X           (AC) "
4410                                                                         "| %s<%s",
4411                                                                         *level, *codepage_stag, tag_new_known,
4412                                                                         Indent (*level), tag_new_literal);
4413                                                         /* Tag string already looked up earlier! */
4414                                                         off++;
4415                                                 } else { /* LITERAL tag */
4416                                                         proto_tree_add_text (tree, tvb, off, 1,
4417                                                                         "  %3d | Tag   | T %3d    "
4418                                                                         "| LITERAL_AC (Literal tag)   (AC) "
4419                                                                         "| %s<%s",
4420                                                                         *level, *codepage_stag, Indent (*level), tag_new_literal);
4421                                                         off += 1 + tag_len;
4422                                                 }
4423                                                 len = parse_wbxml_attribute_list_defined (tree, tvb,
4424                                                                 off, str_tbl, *level, codepage_attr, map);
4425                                                 /* Check that there is still room in packet */
4426                                                 off += len;
4427                                                 if (off >= tvb_len) {
4428                                                         DebugLog(("STAG: level = %u, ThrowException: len = %u (short frame)\n",
4429                                                                                 *level, off - offset));
4430                                                         /*
4431                                                          * TODO - Do we need to free g_malloc()ed memory?
4432                                                          */
4433                                                         THROW(ReportedBoundsError);
4434                                                 }
4435                                                 proto_tree_add_text (tree, tvb, off-1, 1,
4436                                                                 "  %3d | Tag   | T %3d    "
4437                                                                 "| END (attribute list)            "
4438                                                                 "| %s>",
4439                                                                 *level, *codepage_stag, Indent (*level));
4440                                         } else { /* Content, no Attribute list */
4441                                                 if (tag_new_known) { /* Known tag */
4442                                                         proto_tree_add_text (tree, tvb, off, 1,
4443                                                                         "  %3d | Tag   | T %3d    "
4444                                                                         "|   Known Tag 0x%02X           (.C) "
4445                                                                         "| %s<%s>",
4446                                                                         *level, *codepage_stag, tag_new_known,
4447                                                                         Indent (*level), tag_new_literal);
4448                                                         /* Tag string already looked up earlier! */
4449                                                         off++;
4450                                                 } else { /* LITERAL tag */
4451                                                         proto_tree_add_text (tree, tvb, off, 1,
4452                                                                         "  %3d | Tag   | T %3d    "
4453                                                                         "| LITERAL_C  (Literal Tag)   (.C) "
4454                                                                         "| %s<%s>",
4455                                                                         *level, *codepage_stag, Indent (*level),
4456                                                                         tag_new_literal);
4457                                                         off += 1 + tag_len;
4458                                                 }
4459                                         }
4460                                         /* The data that follows in the parsing process
4461                                          * represents content for the opening tag
4462                                          * we've just processed in the lines above.
4463                                          * Next time we encounter a tag with content: recurse
4464                                          */
4465                                         parsing_tag_content = TRUE;
4466                                         DebugLog(("Tag in Tag - No recursion this time! (off = %u)\n", off));
4467                                 }
4468                         } else { /* No Content */
4469                                 DebugLog(("<Tag/> in Tag - No recursion! (off = %u)\n", off));
4470                                 (*level)++;
4471                                 if (peek & 0x80) { /* No Content, Attribute list present */
4472                                         if (tag_new_known) { /* Known tag */
4473                                                 proto_tree_add_text (tree, tvb, off, 1,
4474                                                                 "  %3d | Tag   | T %3d    "
4475                                                                 "|   Known Tag 0x%02X           (A.) "
4476                                                                 "| %s<%s",
4477                                                                 *level, *codepage_stag, tag_new_known,
4478                                                                 Indent (*level), tag_new_literal);
4479                                                 /* Tag string already looked up earlier! */
4480                                                 off++;
4481                                                 len = parse_wbxml_attribute_list_defined (tree, tvb,
4482                                                                 off, str_tbl, *level, codepage_attr, map);
4483                                                 /* Check that there is still room in packet */
4484                                                 off += len;
4485                                                 if (off >= tvb_len) {
4486                                                         DebugLog(("STAG: level = %u, ThrowException: len = %u (short frame)\n", *level, off - offset));
4487                                                         /*
4488                                                          * TODO - Do we need to free g_malloc()ed memory?
4489                                                          */
4490                                                         THROW(ReportedBoundsError);
4491                                                 }
4492                                                 proto_tree_add_text (tree, tvb, off-1, 1,
4493                                                                 "  %3d | Tag   | T %3d    "
4494                                                                 "| END (Known Tag)                 "
4495                                                                 "| %s/>",
4496                                                                 *level, *codepage_stag, Indent (*level));
4497                                         } else { /* LITERAL tag */
4498                                                 proto_tree_add_text (tree, tvb, off, 1,
4499                                                                 "  %3d | Tag   | T %3d    "
4500                                                                 "| LITERAL_A  (Literal Tag)   (A.) "
4501                                                                 "| %s<%s",
4502                                                                 *level, *codepage_stag, Indent (*level), tag_new_literal);
4503                                                 off += 1 + tag_len;
4504                                                 len = parse_wbxml_attribute_list_defined (tree, tvb,
4505                                                                 off, str_tbl, *level, codepage_attr, map);
4506                                                 /* Check that there is still room in packet */
4507                                                 off += len;
4508                                                 if (off >= tvb_len) {
4509                                                         DebugLog(("STAG: level = %u, ThrowException: len = %u (short frame)\n", *level, off - offset));
4510                                                         /*
4511                                                          * TODO - Do we need to free g_malloc()ed memory?
4512                                                          */
4513                                                         THROW(ReportedBoundsError);
4514                                                 }
4515                                                 proto_tree_add_text (tree, tvb, off-1, 1,
4516                                                                 "  %3d | Tag   | T %3d    "
4517                                                                 "| END (Literal Tag)               "
4518                                                                 "| %s/>",
4519                                                                 *level, *codepage_stag, Indent (*level));
4520                                         }
4521                                 } else { /* No Content, No Attribute list */
4522                                         if (tag_new_known) { /* Known tag */
4523                                                 proto_tree_add_text (tree, tvb, off, 1,
4524                                                                 "  %3d | Tag   | T %3d    "
4525                                                                 "|   Known Tag 0x%02x           (..) "
4526                                                                 "| %s<%s />",
4527                                                                 *level, *codepage_stag, tag_new_known,
4528                                                                 Indent (*level), tag_new_literal);
4529                                                 /* Tag string already looked up earlier! */
4530                                                 off++;
4531                                         } else { /* LITERAL tag */
4532                                                 proto_tree_add_text (tree, tvb, off, 1,
4533                                                                 "  %3d | Tag   | T %3d    "
4534                                                                 "| LITERAL    (Literal Tag)   (..) "
4535                                                                 "| %s<%s />",
4536                                                                 *level, *codepage_stag, Indent (*level),
4537                                                                 tag_new_literal);
4538                                                 off += 1 + tag_len;
4539                                         }
4540                                 }
4541                                 (*level)--;
4542                                 /* TODO: Do I have to reset code page here? */
4543                         }
4544                 } /* if (tag & 0x3F) >= 5 */
4545         } /* while */
4546         DebugLog(("STAG: level = %u, Return: len = %u (end of function body)\n", *level, off - offset));
4547         return (off - offset);
4548 }
4549
4550
4551 /* This function performs the WBXML decoding as in parse_wbxml_tag_defined()
4552  * but this time no WBXML mapping is performed.
4553  *
4554  * Attribute parsing is done in parse_wbxml_attribute_list().
4555  */
4556 static guint32
4557 parse_wbxml_tag (proto_tree *tree, tvbuff_t *tvb, guint32 offset,
4558                 guint32 str_tbl, guint8 *level,
4559                 guint8 *codepage_stag, guint8 *codepage_attr)
4560 {
4561         guint32 tvb_len = tvb_reported_length (tvb);
4562         guint32 off = offset;
4563         guint32 len;
4564         guint str_len;
4565         guint32 ent;
4566         guint32 index;
4567         guint8 peek;
4568         guint32 tag_len; /* Length of the index (uintvar) from a LITERAL tag */
4569         guint8 tag_save_known = 0; /* Will contain peek & 0x3F (tag identity) */
4570         guint8 tag_new_known = 0; /* Will contain peek & 0x3F (tag identity) */
4571         const char *tag_save_literal; /* Will contain the LITERAL tag identity */
4572         const char *tag_new_literal; /* Will contain the LITERAL tag identity */
4573         char tag_save_buf[10]; /* Will contain "tag_0x%02X" */
4574         char tag_new_buf[10]; /* Will contain "tag_0x%02X" */
4575         guint8 parsing_tag_content = FALSE; /* Are we parsing content from a
4576                                                                                    tag with content: <x>Content</x>
4577                                                                                    
4578                                                                                    The initial state is FALSE.
4579                                                                                    This state will trigger recursion. */
4580         tag_save_literal = NULL; /* Prevents compiler warning */
4581
4582         DebugLog(("parse_wbxml_tag (level = %u, offset = %u)\n", *level, offset));
4583         while (off < tvb_len) {
4584                 peek = tvb_get_guint8 (tvb, off);
4585                 DebugLog(("STAG: (top of while) level = %3u, peek = 0x%02X, off = %u, tvb_len = %u\n", *level, peek, off, tvb_len));
4586                 if ((peek & 0x3F) < 4) switch (peek) { /* Global tokens in state = STAG
4587                                                                                                   but not the LITERAL tokens */
4588                         case 0x00: /* SWITCH_PAGE */
4589                                 *codepage_stag = tvb_get_guint8 (tvb, off+1);
4590                                 proto_tree_add_text (tree, tvb, off, 2,
4591                                                 "      | Tag   | T -->%3d "
4592                                                 "| SWITCH_PAGE (Tag code page)     "
4593                                                 "|",
4594                                                 *codepage_stag);
4595                                 off += 2;
4596                                 break;
4597                         case 0x01: /* END: only possible for Tag with Content */
4598                                 if (tag_save_known) { /* Known TAG */
4599                                         proto_tree_add_text (tree, tvb, off, 1,
4600                                                         "  %3d | Tag   | T %3d    "
4601                                                         "| END (Known Tag 0x%02X)            "
4602                                                         "| %s</%s>",
4603                                                         *level, *codepage_stag, tag_save_known,
4604                                                         Indent (*level),
4605                                                         tag_save_literal); /* We already looked it up! */
4606                                 } else { /* Literal TAG */
4607                                         proto_tree_add_text (tree, tvb, off, 1,
4608                                                         "  %3d | Tag   | T %3d    "
4609                                                         "| END (Literal Tag)               "
4610                                                         "| %s</%s>",
4611                                                         *level, *codepage_stag, Indent (*level),
4612                                                         tag_save_literal);
4613                                 }
4614                                 (*level)--;
4615                                 off++;
4616                                 /* Reset code page: not needed as return from recursion */
4617                                 DebugLog(("STAG: level = %u, Return: len = %u\n",
4618                                                         *level, off - offset));
4619                                 return (off - offset);
4620                                 break;
4621                         case 0x02: /* ENTITY */
4622                                 ent = tvb_get_guintvar (tvb, off+1, &len);
4623                                 proto_tree_add_text (tree, tvb, off, 1+len,
4624                                                 "  %3d | Tag   | T %3d    "
4625                                                 "| ENTITY                          "
4626                                                 "| %s'&#%u;'",
4627                                                 *level, *codepage_stag, Indent (*level), ent);
4628                                 off += 1+len;
4629                                 break;
4630                         case 0x03: /* STR_I */
4631                                 len = tvb_strsize (tvb, off+1);
4632                                 proto_tree_add_text (tree, tvb, off, 1+len,
4633                                                 "  %3d | Tag   | T %3d    "
4634                                                 "| STR_I (Inline string)           "
4635                                                 "| %s\'%s\'",
4636                                                 *level, *codepage_stag, Indent(*level),
4637                                                 tvb_format_text (tvb, off+1, len-1));
4638                                 off += 1+len;
4639                                 break;
4640                         case 0x40: /* EXT_I_0 */
4641                         case 0x41: /* EXT_I_1 */
4642                         case 0x42: /* EXT_I_2 */
4643                                 /* Extension tokens */
4644                                 len = tvb_strsize (tvb, off+1);
4645                                 proto_tree_add_text (tree, tvb, off, 1+len,
4646                                                 "  %3d | Tag   | T %3d    "
4647                                                 "| EXT_I_%1x    (Extension Token)    "
4648                                                 "| %s(Inline string extension: \'%s\')",
4649                                                 *level, *codepage_stag, peek & 0x0f, Indent (*level),
4650                                                 tvb_format_text (tvb, off+1, len-1));
4651                                 off += 1+len;
4652                                 break;
4653                         case 0x43: /* PI */
4654                                 proto_tree_add_text (tree, tvb, off, 1,
4655                                                 "  %3d | Tag   | T %3d    "
4656                                                 "| PI (XML Processing Instruction) "
4657                                                 "| %s<?xml",
4658                                                 *level, *codepage_stag, Indent (*level));
4659                                 len = parse_wbxml_attribute_list (tree, tvb, off, str_tbl,
4660                                                 *level, codepage_attr);
4661                                 /* Check that there is still room in packet */
4662                                 off += len;
4663                                 if (off >= tvb_len) {
4664                                         DebugLog(("STAG: level = %u, ThrowException: len = %u (short frame)\n",
4665                                                                 *level, off - offset));
4666                                         /*
4667                                          * TODO - Do we need to free g_malloc()ed memory?
4668                                          */
4669                                         THROW(ReportedBoundsError);
4670                                 }
4671                                 proto_tree_add_text (tree, tvb, off-1, 1,
4672                                                 "  %3d | Tag   | T %3d    "
4673                                                 "| END (PI)                        "
4674                                                 "| %s?>",
4675                                                 *level, *codepage_stag, Indent (*level));
4676                                 break;
4677                         case 0x80: /* EXT_T_0 */
4678                         case 0x81: /* EXT_T_1 */
4679                         case 0x82: /* EXT_T_2 */
4680                                 /* Extension tokens */
4681                                 index = tvb_get_guintvar (tvb, off+1, &len);
4682                                 str_len = tvb_strsize (tvb, str_tbl+index);
4683                                 proto_tree_add_text (tree, tvb, off, 1+len,
4684                                                 "  %3d | Tag   | T %3d    "
4685                                                 "| EXT_T_%1x    (Extension Token)    "
4686                                                 "| %s(Extension Token, integer value: %u)",
4687                                                 *level, *codepage_stag, peek & 0x0f, Indent (*level),
4688                                                 index);
4689                                 off += 1+len;
4690                                 break;
4691                         case 0x83: /* STR_T */
4692                                 index = tvb_get_guintvar (tvb, off+1, &len);
4693                                 str_len = tvb_strsize (tvb, str_tbl+index);
4694                                 proto_tree_add_text (tree, tvb, off, 1+len,
4695                                                 "  %3d | Tag   | T %3d    "
4696                                                 "| STR_T (Tableref string)         "
4697                                                 "| %s\'%s\'",
4698                                                 *level, *codepage_stag, Indent (*level),
4699                                                 tvb_format_text (tvb, str_tbl+index, str_len-1));
4700                                 off += 1+len;
4701                                 break;
4702                         case 0xC0: /* EXT_0 */
4703                         case 0xC1: /* EXT_1 */
4704                         case 0xC2: /* EXT_2 */
4705                                 /* Extension tokens */
4706                                 proto_tree_add_text (tree, tvb, off, 1,
4707                                                 "  %3d | Tag   | T %3d    "
4708                                                 "| EXT_%1x      (Extension Token)    "
4709                                                 "| %s(Single-byte extension)",
4710                                                 *level, *codepage_stag, peek & 0x0f, Indent (*level));
4711                                 off++;
4712                                 break;
4713                         case 0xC3: /* OPAQUE - WBXML 1.1 and newer */
4714                                 if (tvb_get_guint8 (tvb, 0)) { /* WBXML 1.x (x > 0) */
4715                                         index = tvb_get_guintvar (tvb, off+1, &len);
4716                                         proto_tree_add_text (tree, tvb, off, 1 + len + index,
4717                                                         "  %3d | Tag   | T %3d    "
4718                                                         "| OPAQUE (Opaque data)            "
4719                                                         "| %s(%d bytes of opaque data)",
4720                                                         *level, *codepage_stag, Indent (*level), index);
4721                                         off += 1+len+index;
4722                                 } else { /* WBXML 1.0 - RESERVED_2 token (invalid) */
4723                                         proto_tree_add_text (tree, tvb, off, 1,
4724                                                         "  %3d | Tag   | T %3d    "
4725                                                         "| RESERVED_2     (Invalid Token!) "
4726                                                         "| WBXML 1.0 parsing stops here.",
4727                                                         *level, *codepage_stag);
4728                                         /* Stop processing as it is impossible to parse now */
4729                                         off = tvb_len;
4730                                         DebugLog(("STAG: level = %u, Return: len = %u\n",
4731                                                                 *level, off - offset));
4732                                         return (off - offset);
4733                                 }
4734                                 break;
4735
4736                                 /* No default clause, as all cases have been treated */
4737                 } else { /* LITERAL or Known TAG */
4738                         /* We must store the initial tag, and also retrieve the new tag.
4739                          * For efficiency reasons, we store the literal tag representation
4740                          * for known tags too, so we can easily close the tag without the
4741                          * need of a new lookup and avoiding storage of token codepage.
4742                          * 
4743                          * There are 4 possibilities:
4744                          *
4745                          *  1. Known tag followed by a known tag
4746                          *  2. Known tag followed by a LITERAL tag
4747                          *  3. LITERAL tag followed by Known tag
4748                          *  4. LITERAL tag followed by LITERAL tag
4749                          */
4750
4751                         /* Store the new tag */
4752                         tag_len = 0;
4753                         if ((peek & 0x3F) == 4) { /* LITERAL */
4754                                 DebugLog(("STAG: LITERAL tag (peek = 0x%02X, off = %u)"
4755                                                         " - TableRef follows!\n", peek, off));
4756                                 index = tvb_get_guintvar (tvb, off+1, &tag_len);
4757                                 str_len = tvb_strsize (tvb, str_tbl+index);
4758                                 tag_new_literal = tvb_get_ptr (tvb, str_tbl+index, str_len);
4759                                 tag_new_known = 0; /* invalidate known tag_new */
4760                         } else { /* Known tag */
4761                                 tag_new_known = peek & 0x3F;
4762                                 sprintf (tag_new_buf, "Tag_0x%02X",
4763                                                 tag_new_known);
4764                                 tag_new_literal = tag_new_buf;
4765                                 /* Stored looked up tag name string */
4766                         }
4767
4768                         /* Parsing of TAG starts HERE */
4769                         if (peek & 0x40) { /* Content present */
4770                                 /* Content follows
4771                                  * [!] An explicit END token is expected in these cases!
4772                                  * ==> Recursion possible if we encounter a tag with content;
4773                                  *     recursion will return at the explicit END token.
4774                                  */
4775                                 if (parsing_tag_content) { /* Recurse */
4776                                         DebugLog(("STAG: Tag in Tag - RECURSE! (off = %u)\n", off));
4777                                         /* Do not process the attribute list:
4778                                          * recursion will take care of it */
4779                                         (*level)++;
4780                                         len = parse_wbxml_tag (tree, tvb, off, str_tbl, level,
4781                                                         codepage_stag, codepage_attr);
4782                                         off += len;
4783                                 } else { /* Now we will have content to parse */
4784                                         /* Save the start tag so we can properly close it later. */
4785                                         if ((peek & 0x3F) == 4) { /* Literal tag */
4786                                                 tag_save_literal = tag_new_literal;
4787                                                 tag_save_known = 0;
4788                                         } else { /* Known tag */
4789                                                 tag_save_known = tag_new_known;
4790                                                 sprintf (tag_save_buf, "Tag_0x%02X",
4791                                                                 tag_new_known);
4792                                                 tag_save_literal = tag_save_buf;
4793                                                 /* The last statement avoids needless lookups */
4794                                         }
4795                                         /* Process the attribute list if present */
4796                                         if (peek & 0x80) { /* Content and Attribute list present */
4797                                                 if (tag_new_known) { /* Known tag */
4798                                                         proto_tree_add_text (tree, tvb, off, 1,
4799                                                                         "  %3d | Tag   | T %3d    "
4800                                                                         "|   Known Tag 0x%02X           (AC) "
4801                                                                         "| %s<%s",
4802                                                                         *level, *codepage_stag, tag_new_known,
4803                                                                         Indent (*level), tag_new_literal);
4804                                                         /* Tag string already looked up earlier! */
4805                                                         off++;
4806                                                 } else { /* LITERAL tag */
4807                                                         proto_tree_add_text (tree, tvb, off, 1,
4808                                                                         "  %3d | Tag   | T %3d    "
4809                                                                         "| LITERAL_AC (Literal tag)   (AC) "
4810                                                                         "| %s<%s",
4811                                                                         *level, *codepage_stag, Indent (*level),
4812                                                                         tag_new_literal);
4813                                                         off += 1 + tag_len;
4814                                                 }
4815                                                 len = parse_wbxml_attribute_list (tree, tvb,
4816                                                                 off, str_tbl, *level, codepage_attr);
4817                                                 /* Check that there is still room in packet */
4818                                                 off += len;
4819                                                 if (off >= tvb_len) {
4820                                                         DebugLog(("STAG: level = %u, ThrowException: "
4821                                                                                 "len = %u (short frame)\n",
4822                                                                                 *level, off - offset));
4823                                                         /*
4824                                                          * TODO - Do we need to free g_malloc()ed memory?
4825                                                          */
4826                                                         THROW(ReportedBoundsError);
4827                                                 }
4828                                                 proto_tree_add_text (tree, tvb, off-1, 1,
4829                                                                 "  %3d | Tag   | T %3d    "
4830                                                                 "| END (attribute list)            "
4831                                                                 "| %s>",
4832                                                                 *level, *codepage_stag, Indent (*level));
4833                                         } else { /* Content, no Attribute list */
4834                                                 if (tag_new_known) { /* Known tag */
4835                                                         proto_tree_add_text (tree, tvb, off, 1,
4836                                                                         "  %3d | Tag   | T %3d    "
4837                                                                         "|   Known Tag 0x%02X           (.C) "
4838                                                                         "| %s<%s>",
4839                                                                         *level, *codepage_stag, tag_new_known,
4840                                                                         Indent (*level), tag_new_literal);
4841                                                         /* Tag string already looked up earlier! */
4842                                                         off++;
4843                                                 } else { /* LITERAL tag */
4844                                                         proto_tree_add_text (tree, tvb, off, 1,
4845                                                                         "  %3d | Tag   | T %3d    "
4846                                                                         "| LITERAL_C  (Literal Tag)   (.C) "
4847                                                                         "| %s<%s>",
4848                                                                         *level, *codepage_stag, Indent (*level),
4849                                                                         tag_new_literal);
4850                                                         off += 1 + tag_len;
4851                                                 }
4852                                         }
4853                                         /* The data that follows in the parsing process
4854                                          * represents content for the opening tag
4855                                          * we've just processed in the lines above.
4856                                          * Next time we encounter a tag with content: recurse
4857                                          */
4858                                         parsing_tag_content = TRUE;
4859                                         DebugLog(("Tag in Tag - No recursion this time! "
4860                                                                 "(off = %u)\n", off));
4861                                 }
4862                         } else { /* No Content */
4863                                 DebugLog(("<Tag/> in Tag - No recursion! (off = %u)\n", off));
4864                                 (*level)++;
4865                                 if (peek & 0x80) { /* No Content, Attribute list present */
4866                                         if (tag_new_known) { /* Known tag */
4867                                                 proto_tree_add_text (tree, tvb, off, 1,
4868                                                                 "  %3d | Tag   | T %3d    "
4869                                                                 "|   Known Tag 0x%02X           (A.) "
4870                                                                 "| %s<%s",
4871                                                                 *level, *codepage_stag, tag_new_known,
4872                                                                 Indent (*level), tag_new_literal);
4873                                                 /* Tag string already looked up earlier! */
4874                                                 off++;
4875                                                 len = parse_wbxml_attribute_list (tree, tvb,
4876                                                                 off, str_tbl, *level, codepage_attr);
4877                                                 /* Check that there is still room in packet */
4878                                                 off += len;
4879                                                 if (off >= tvb_len) {
4880                                                         DebugLog(("STAG: level = %u, ThrowException: "
4881                                                                                 "len = %u (short frame)\n",
4882                                                                                 *level, off - offset));
4883                                                         /*
4884                                                          * TODO - Do we need to free g_malloc()ed memory?
4885                                                          */
4886                                                         THROW(ReportedBoundsError);
4887                                                 }
4888                                                 proto_tree_add_text (tree, tvb, off-1, 1,
4889                                                                 "  %3d | Tag   | T %3d    "
4890                                                                 "| END (Known Tag)                 "
4891                                                                 "| %s/>",
4892                                                                 *level, *codepage_stag, Indent (*level));
4893                                         } else { /* LITERAL tag */
4894                                                 proto_tree_add_text (tree, tvb, off, 1,
4895                                                                 "  %3d | Tag   | T %3d    "
4896                                                                 "| LITERAL_A  (Literal Tag)   (A.) "
4897                                                                 "| %s<%s",
4898                                                                 *level, *codepage_stag, Indent (*level),
4899                                                                 tag_new_literal);
4900                                                 off += 1 + tag_len;
4901                                                 len = parse_wbxml_attribute_list (tree, tvb,
4902                                                                 off, str_tbl, *level, codepage_attr);
4903                                                 /* Check that there is still room in packet */
4904                                                 off += len;
4905                                                 if (off >= tvb_len) {
4906                                                         DebugLog(("STAG: level = %u, ThrowException: "
4907                                                                                 "len = %u (short frame)\n",
4908                                                                                 *level, off - offset));
4909                                                         /*
4910                                                          * TODO - Do we need to free g_malloc()ed memory?
4911                                                          */
4912                                                         THROW(ReportedBoundsError);
4913                                                 }
4914                                                 proto_tree_add_text (tree, tvb, off-1, 1,
4915                                                                 "  %3d | Tag   | T %3d    "
4916                                                                 "| END (Literal Tag)               "
4917                                                                 "| %s/>",
4918                                                                 *level, *codepage_stag, Indent (*level));
4919                                         }
4920                                 } else { /* No Content, No Attribute list */
4921                                         if (tag_new_known) { /* Known tag */
4922                                                 proto_tree_add_text (tree, tvb, off, 1,
4923                                                                 "  %3d | Tag   | T %3d    "
4924                                                                 "|   Known Tag 0x%02x           (..) "
4925                                                                 "| %s<%s />",
4926                                                                 *level, *codepage_stag, tag_new_known,
4927                                                                 Indent (*level), tag_new_literal);
4928                                                 /* Tag string already looked up earlier! */
4929                                                 off++;
4930                                         } else { /* LITERAL tag */
4931                                                 proto_tree_add_text (tree, tvb, off, 1,
4932                                                                 "  %3d | Tag   | T %3d    "
4933                                                                 "| LITERAL    (Literal Tag)   (..) "
4934                                                                 "| %s<%s />",
4935                                                                 *level, *codepage_stag, Indent (*level),
4936                                                                 tag_new_literal);
4937                                                 off += 1 + tag_len;
4938                                         }
4939                                 }
4940                                 (*level)--;
4941                                 /* TODO: Do I have to reset code page here? */
4942                         }
4943                 } /* if (tag & 0x3F) >= 5 */
4944         } /* while */
4945         DebugLog(("STAG: level = %u, Return: len = %u (end of function body)\n",
4946                                 *level, off - offset));
4947         return (off - offset);
4948 }
4949
4950
4951 /**************************
4952  * WBXML Attribute tokens *
4953  **************************
4954  * Bit Mask  : Example
4955  * -------------------
4956  * 0... .... : attr=             (attribute name)
4957  *             href='http://'    (attribute name with start of attribute value)
4958  * 1... .... : 'www.'            (attribute value, or part of it)
4959  * 
4960  */
4961
4962
4963 /* This function parses the WBXML and maps known token interpretations
4964  * to the WBXML tokens. As a result, the original XML document can be
4965  * recreated. Indentation is generated in order to ease reading.
4966  *
4967  * This function performs attribute list parsing.
4968  * 
4969  * The wbxml_decoding entry *map contains the actual token mapping.
4970  *
4971  * NOTE: See above for known token mappings.
4972  */
4973 static guint32
4974 parse_wbxml_attribute_list_defined (proto_tree *tree, tvbuff_t *tvb,
4975                 guint32 offset, guint32 str_tbl, guint8 level, guint8 *codepage_attr,
4976                 const wbxml_decoding *map)
4977 {
4978         guint32 tvb_len = tvb_reported_length (tvb);
4979         guint32 off = offset;
4980         guint32 len;
4981         guint str_len;
4982         guint32 ent;
4983         guint32 index;
4984         guint8 peek;
4985
4986         DebugLog(("parse_wbxml_attr_defined (level = %u, offset = %u)\n",
4987                                 level, offset));
4988         /* Parse attributes */
4989         while (off < tvb_len) {
4990                 peek = tvb_get_guint8 (tvb, off);
4991                 DebugLog(("ATTR: (top of while) level = %3u, peek = 0x%02X, "
4992                                         "off = %u, tvb_len = %u\n", level, peek, off, tvb_len));
4993                 if ((peek & 0x3F) < 5) switch (peek) { /* Global tokens
4994                                                                                                   in state = ATTR */
4995                         case 0x00: /* SWITCH_PAGE */
4996                                 *codepage_attr = tvb_get_guint8 (tvb, off+1);
4997                                 proto_tree_add_text (tree, tvb, off, 2,
4998                                                 "      |  Attr | A -->%3d "
4999                                                 "| SWITCH_PAGE (Attr code page)    |",
5000                                                 *codepage_attr);
5001                                 off += 2;
5002                                 break;
5003                         case 0x01: /* END */
5004                                 /* BEWARE
5005                                  *   The Attribute END token means either ">" or "/>"
5006                                  *   and as a consequence both must be treated separately.
5007                                  *   This is done in the TAG state parser.
5008                                  */
5009                                 off++;
5010                                 DebugLog(("ATTR: level = %u, Return: len = %u\n",
5011                                                         level, off - offset));
5012                                 return (off - offset);
5013                         case 0x02: /* ENTITY */
5014                                 ent = tvb_get_guintvar (tvb, off+1, &len);
5015                                 proto_tree_add_text (tree, tvb, off, 1+len,
5016                                                 "  %3d |  Attr | A %3d    "
5017                                                 "| ENTITY                          "
5018                                                 "|     %s'&#%u;'",
5019                                                 level, *codepage_attr, Indent (level), ent);
5020                                 off += 1+len;
5021                                 break;
5022                         case 0x03: /* STR_I */
5023                                 len = tvb_strsize (tvb, off+1);
5024                                 proto_tree_add_text (tree, tvb, off, 1+len,
5025                                                 "  %3d |  Attr | A %3d    "
5026                                                 "| STR_I (Inline string)           "
5027                                                 "|     %s\'%s\'",
5028                                                 level, *codepage_attr, Indent (level),
5029                                                 tvb_format_text (tvb, off+1, len-1));
5030                                 off += 1+len;
5031                                 break;
5032                         case 0x04: /* LITERAL */
5033                                 index = tvb_get_guintvar (tvb, off+1, &len);
5034                                 str_len = tvb_strsize (tvb, str_tbl+index);
5035                                 proto_tree_add_text (tree, tvb, off, 1+len,
5036                                                 "  %3d |  Attr | A %3d    "
5037                                                 "| LITERAL (Literal Attribute)     "
5038                                                 "|   %s<%s />",
5039                                                 level, *codepage_attr, Indent (level),
5040                                                 tvb_format_text (tvb, str_tbl+index, str_len-1));
5041                                 off += 1+len;
5042                                 break;
5043                         case 0x40: /* EXT_I_0 */
5044                         case 0x41: /* EXT_I_1 */
5045                         case 0x42: /* EXT_I_2 */
5046                                 /* Extension tokens */
5047                                 len = tvb_strsize (tvb, off+1);
5048                                 proto_tree_add_text (tree, tvb, off, 1+len,
5049                                                 "  %3d |  Attr | A %3d    "
5050                                                 "| EXT_I_%1x    (Extension Token)    "
5051                                                 "|     %s(%s: \'%s\')",
5052                                                 level, *codepage_attr, peek & 0x0f, Indent (level),
5053                                                 map_token (map->global, 0, peek),
5054                                                 tvb_format_text (tvb, off+1, len-1));
5055                                 off += 1+len;
5056                                 break;
5057                         /* 0x43 impossible in ATTR state */
5058                         /* 0x44 impossible in ATTR state */
5059                         case 0x80: /* EXT_T_0 */
5060                         case 0x81: /* EXT_T_1 */
5061                         case 0x82: /* EXT_T_2 */
5062                                 /* Extension tokens */
5063                                 index = tvb_get_guintvar (tvb, off+1, &len);
5064                                 str_len = tvb_strsize (tvb, str_tbl+index);
5065                                 {   char *s;
5066
5067                                     if (map->ext_t[peek & 0x03])
5068                                         s = (map->ext_t[peek & 0x03])(tvb, index, str_tbl);
5069                                     else
5070                                         s = g_strdup_printf("EXT_T_%1x (%s)", peek & 0x03, 
5071                                                 map_token (map->global, 0, peek));
5072
5073                                     proto_tree_add_text (tree, tvb, off, 1+len,
5074                                                 "  %3d | Tag   | T %3d    "
5075                                                 "| EXT_T_%1x    (Extension Token)    "
5076                                                 "| %s%s)",
5077                                                 level, *codepage_attr, peek & 0x0f, Indent (level),
5078                                                 s);
5079                                     g_free(s);
5080                                 }
5081                                 proto_tree_add_text (tree, tvb, off, 1+len,
5082                                                 "  %3d |  Attr | A %3d    "
5083                                                 "| EXT_T_%1x    (Extension Token)    "
5084                                                 "|     %s(%s: \'%s\')",
5085                                                 level, *codepage_attr, peek & 0x0f, Indent (level),
5086                                                 map_token (map->global, 0, peek),
5087                                                 tvb_format_text (tvb, str_tbl+index, str_len-1));
5088                                 off += 1+len;
5089                                 break;
5090                         case 0x83: /* STR_T */
5091                                 index = tvb_get_guintvar (tvb, off+1, &len);
5092                                 str_len = tvb_strsize (tvb, str_tbl+index);
5093                                 proto_tree_add_text (tree, tvb, off, 1+len,
5094                                                 "  %3d |  Attr | A %3d    "
5095                                                 "| STR_T (Tableref string)         "
5096                                                 "|     %s\'%s\'",
5097                                                 level, *codepage_attr, Indent (level),
5098                                                 tvb_format_text (tvb, str_tbl+index, str_len-1));
5099                                 off += 1+len;
5100                                 break;
5101                         /* 0x84 impossible in ATTR state */
5102                         case 0xC0: /* EXT_0 */
5103                         case 0xC1: /* EXT_1 */
5104                         case 0xC2: /* EXT_2 */
5105                                 /* Extension tokens */
5106                                 proto_tree_add_text (tree, tvb, off, 1,
5107                                                 "  %3d |  Attr | A %3d    "
5108                                                 "| EXT_%1x      (Extension Token)    "
5109                                                 "|     %s(%s)",
5110                                                 level, *codepage_attr, peek & 0x0f, Indent (level),
5111                                                 map_token (map->global, 0, peek));
5112                                 off++;
5113                                 break;
5114                         case 0xC3: /* OPAQUE - WBXML 1.1 and newer */
5115                                 if (tvb_get_guint8 (tvb, 0)) { /* WBXML 1.x (x > 0) */
5116                                         index = tvb_get_guintvar (tvb, off+1, &len);
5117                                         proto_tree_add_text (tree, tvb, off, 1 + len + index,
5118                                                         "  %3d |  Attr | A %3d    "
5119                                                         "| OPAQUE (Opaque data)            "
5120                                                         "|       %s(%d bytes of opaque data)",
5121                                                         level, *codepage_attr, Indent (level), index);
5122                                         off += 1+len+index;
5123                                 } else { /* WBXML 1.0 - RESERVED_2 token (invalid) */
5124                                         proto_tree_add_text (tree, tvb, off, 1,
5125                                                         "  %3d |  Attr | A %3d    "
5126                                                         "| RESERVED_2     (Invalid Token!) "
5127                                                         "| WBXML 1.0 parsing stops here.",
5128                                                         level, *codepage_attr);
5129                                         /* Stop processing as it is impossible to parse now */
5130                                         off = tvb_len;
5131                                         DebugLog(("ATTR: level = %u, Return: len = %u\n",
5132                                                                 level, off - offset));
5133                                         return (off - offset);
5134                                 }
5135                                 break;
5136                         /* 0xC4 impossible in ATTR state */
5137                         default:
5138                                 proto_tree_add_text (tree, tvb, off, 1,
5139                                                 "  %3d |  Attr | A %3d    "
5140                                                 "| %-10s     (Invalid Token!) "
5141                                                 "| WBXML parsing stops here.",
5142                                                 level, *codepage_attr,
5143                                                 match_strval (peek, vals_wbxml1x_global_tokens));
5144                                 /* Move to end of buffer */
5145                                 off = tvb_len;
5146                                 break;
5147                 } else { /* Known atribute token */
5148                         if (peek & 0x80) { /* attrValue */
5149                                 proto_tree_add_text (tree, tvb, off, 1,
5150                                                 "  %3d |  Attr | A %3d    "
5151                                                 "|   Known attrValue 0x%02X          "
5152                                                 "|       %s%s",
5153                                                 level, *codepage_attr, peek & 0x7f, Indent (level),
5154                                                 map_token (map->attrValue, *codepage_attr, peek));
5155                                 off++;
5156                         } else { /* attrStart */
5157                                 proto_tree_add_text (tree, tvb, off, 1,
5158                                                 "  %3d |  Attr | A %3d    "
5159                                                 "|   Known attrStart 0x%02X          "
5160                                                 "|   %s%s",
5161                                                 level, *codepage_attr, peek & 0x7f, Indent (level),
5162                                                 map_token (map->attrStart, *codepage_attr, peek));
5163                                 off++;
5164                         }
5165                 }
5166         } /* End WHILE */
5167         DebugLog(("ATTR: level = %u, Return: len = %u (end of function body)\n",
5168                                 level, off - offset));
5169         return (off - offset);
5170 }
5171
5172
5173 /* This function performs the WBXML attribute decoding as in
5174  * parse_wbxml_attribute_list_defined() but this time no WBXML mapping
5175  * is performed.
5176  *
5177  * This function performs attribute list parsing.
5178  * 
5179  * NOTE: Code page switches not yet processed in the code!
5180  */
5181 static guint32
5182 parse_wbxml_attribute_list (proto_tree *tree, tvbuff_t *tvb,
5183                 guint32 offset, guint32 str_tbl, guint8 level, guint8 *codepage_attr)
5184 {
5185         guint32 tvb_len = tvb_reported_length (tvb);
5186         guint32 off = offset;
5187         guint32 len;
5188         guint str_len;
5189         guint32 ent;
5190         guint32 index;
5191         guint8 peek;
5192
5193         DebugLog(("parse_wbxml_attr (level = %u, offset = %u)\n", level, offset));
5194         /* Parse attributes */
5195         while (off < tvb_len) {
5196                 peek = tvb_get_guint8 (tvb, off);
5197                 DebugLog(("ATTR: (top of while) level = %3u, peek = 0x%02X, "
5198                                         "off = %u, tvb_len = %u\n", level, peek, off, tvb_len));
5199                 if ((peek & 0x3F) < 5) switch (peek) { /* Global tokens
5200                                                                                                   in state = ATTR */
5201                         case 0x00: /* SWITCH_PAGE */
5202                                 *codepage_attr = tvb_get_guint8 (tvb, off+1);
5203                                 proto_tree_add_text (tree, tvb, off, 2,
5204                                                 "      |  Attr | A -->%3d "
5205                                                 "| SWITCH_PAGE (Attr code page)    |",
5206                                                 *codepage_attr);
5207                                 off += 2;
5208                                 break;
5209                         case 0x01: /* END */
5210                                 /* BEWARE
5211                                  *   The Attribute END token means either ">" or "/>"
5212                                  *   and as a consequence both must be treated separately.
5213                                  *   This is done in the TAG state parser.
5214                                  */
5215                                 off++;
5216                                 DebugLog(("ATTR: level = %u, Return: len = %u\n",
5217                                                         level, off - offset));
5218                                 return (off - offset);
5219                         case 0x02: /* ENTITY */
5220                                 ent = tvb_get_guintvar (tvb, off+1, &len);
5221                                 proto_tree_add_text (tree, tvb, off, 1+len,
5222                                                 "  %3d |  Attr | A %3d    "
5223                                                 "| ENTITY                          "
5224                                                 "|     %s'&#%u;'",
5225                                                 level, *codepage_attr, Indent (level), ent);
5226                                 off += 1+len;
5227                                 break;
5228                         case 0x03: /* STR_I */
5229                                 len = tvb_strsize (tvb, off+1);
5230                                 proto_tree_add_text (tree, tvb, off, 1+len,
5231                                                 "  %3d |  Attr | A %3d    "
5232                                                 "| STR_I (Inline string)           "
5233                                                 "|     %s\'%s\'",
5234                                                 level, *codepage_attr, Indent (level),
5235                                                 tvb_format_text (tvb, off+1, len-1));
5236                                 off += 1+len;
5237                                 break;
5238                         case 0x04: /* LITERAL */
5239                                 index = tvb_get_guintvar (tvb, off+1, &len);
5240                                 str_len = tvb_strsize (tvb, str_tbl+index);
5241                                 proto_tree_add_text (tree, tvb, off, 1+len,
5242                                                 "  %3d |  Attr | A %3d    "
5243                                                 "| LITERAL (Literal Attribute)     "
5244                                                 "|   %s<%s />",
5245                                                 level, *codepage_attr, Indent (level),
5246                                                 tvb_format_text (tvb, str_tbl+index, str_len-1));
5247                                 off += 1+len;
5248                                 break;
5249                         case 0x40: /* EXT_I_0 */
5250                         case 0x41: /* EXT_I_1 */
5251                         case 0x42: /* EXT_I_2 */
5252                                 /* Extension tokens */
5253                                 len = tvb_strsize (tvb, off+1);
5254                                 proto_tree_add_text (tree, tvb, off, 1+len,
5255                                                 "  %3d |  Attr | A %3d    "
5256                                                 "| EXT_I_%1x    (Extension Token)    "
5257                                                 "|     %s(Inline string extension: \'%s\')",
5258                                                 level, *codepage_attr, peek & 0x0f, Indent (level),
5259                                                 tvb_format_text (tvb, off+1, len-1));
5260                                 off += 1+len;
5261                                 break;
5262                         /* 0x43 impossible in ATTR state */
5263                         /* 0x44 impossible in ATTR state */
5264                         case 0x80: /* EXT_T_0 */
5265                         case 0x81: /* EXT_T_1 */
5266                         case 0x82: /* EXT_T_2 */
5267                                 /* Extension tokens */
5268                                 index = tvb_get_guintvar (tvb, off+1, &len);
5269                                 str_len = tvb_strsize (tvb, str_tbl+index);
5270                                 proto_tree_add_text (tree, tvb, off, 1+len,
5271                                                 "  %3d |  Attr | A %3d    "
5272                                                 "| EXT_T_%1x    (Extension Token)    "
5273                                                 "|     %s(Extension Token, integer value: %u)",
5274                                                 level, *codepage_attr, peek & 0x0f, Indent (level),
5275                                                 index);
5276                                 off += 1+len;
5277                                 break;
5278                         case 0x83: /* STR_T */
5279                                 index = tvb_get_guintvar (tvb, off+1, &len);
5280                                 str_len = tvb_strsize (tvb, str_tbl+index);
5281                                 proto_tree_add_text (tree, tvb, off, 1+len,
5282                                                 "  %3d |  Attr | A %3d    "
5283                                                 "| STR_T (Tableref string)         "
5284                                                 "|     %s\'%s\'",
5285                                                 level, *codepage_attr, Indent (level),
5286                                                 tvb_format_text (tvb, str_tbl+index, str_len-1));
5287                                 off += 1+len;
5288                                 break;
5289                         /* 0x84 impossible in ATTR state */
5290                         case 0xC0: /* EXT_0 */
5291                         case 0xC1: /* EXT_1 */
5292                         case 0xC2: /* EXT_2 */
5293                                 /* Extension tokens */
5294                                 proto_tree_add_text (tree, tvb, off, 1,
5295                                                 "  %3d |  Attr | A %3d    "
5296                                                 "| EXT_%1x      (Extension Token)    "
5297                                                 "|     %s(Single-byte extension)",
5298                                                 level, *codepage_attr, peek & 0x0f, Indent (level));
5299                                 off++;
5300                                 break;
5301                         case 0xC3: /* OPAQUE - WBXML 1.1 and newer */
5302                                 if (tvb_get_guint8 (tvb, 0)) { /* WBXML 1.x (x > 0) */
5303                                         index = tvb_get_guintvar (tvb, off+1, &len);
5304                                         proto_tree_add_text (tree, tvb, off, 1 + len + index,
5305                                                         "  %3d |  Attr | A %3d    "
5306                                                         "| OPAQUE (Opaque data)            "
5307                                                         "|       %s(%d bytes of opaque data)",
5308                                                         level, *codepage_attr, Indent (level), index);
5309                                         off += 1+len+index;
5310                                 } else { /* WBXML 1.0 - RESERVED_2 token (invalid) */
5311                                         proto_tree_add_text (tree, tvb, off, 1,
5312                                                         "  %3d |  Attr | A %3d    "
5313                                                         "| RESERVED_2     (Invalid Token!) "
5314                                                         "| WBXML 1.0 parsing stops here.",
5315                                                         level, *codepage_attr);
5316                                         /* Stop processing as it is impossible to parse now */
5317                                         off = tvb_len;
5318                                         DebugLog(("ATTR: level = %u, Return: len = %u\n",
5319                                                                 level, off - offset));
5320                                         return (off - offset);
5321                                 }
5322                                 break;
5323                         /* 0xC4 impossible in ATTR state */
5324                         default:
5325                                 proto_tree_add_text (tree, tvb, off, 1,
5326                                                 "  %3d |  Attr | A %3d    "
5327                                                 "| %-10s     (Invalid Token!) "
5328                                                 "| WBXML parsing stops here.",
5329                                                 level, *codepage_attr,
5330                                                 match_strval (peek, vals_wbxml1x_global_tokens));
5331                                 /* Move to end of buffer */
5332                                 off = tvb_len;
5333                                 break;
5334                 } else { /* Known atribute token */
5335                         if (peek & 0x80) { /* attrValue */
5336                                 proto_tree_add_text (tree, tvb, off, 1,
5337                                                 "  %3d |  Attr | A %3d    "
5338                                                 "|   Known attrValue 0x%02X          "
5339                                                 "|       %sattrValue_0x%02X",
5340                                                 level, *codepage_attr, peek & 0x7f, Indent (level),
5341                                                 peek);
5342                                 off++;
5343                         } else { /* attrStart */
5344                                 proto_tree_add_text (tree, tvb, off, 1,
5345                                                 "  %3d |  Attr | A %3d    "
5346                                                 "|   Known attrStart 0x%02X          "
5347                                                 "|   %sattrStart_0x%02X",
5348                                                 level, *codepage_attr, peek & 0x7f, Indent (level),
5349                                                 peek);
5350                                 off++;
5351                         }
5352                 }
5353         } /* End WHILE */
5354         DebugLog(("ATTR: level = %u, Return: len = %u (end of function body)\n",
5355                                 level, off - offset));
5356         return (off - offset);
5357 }
5358
5359
5360 /****************** Register the protocol with Ethereal ******************/
5361
5362
5363 /* This format is required because a script is used to build the C function
5364  * that calls the protocol registration. */
5365
5366 void
5367 proto_register_wbxml(void)
5368 { /* Setup list of header fields. See Section 1.6.1 for details. */
5369         static hf_register_info hf[] = {
5370                 { &hf_wbxml_version,
5371                         { "Version",
5372                           "wbxml.version",
5373                           FT_UINT8, BASE_HEX,
5374                           VALS ( vals_wbxml_versions ), 0x00,
5375                           "WBXML Version", HFILL }
5376                 },
5377                 { &hf_wbxml_public_id_known,
5378                         { "Public Identifier (known)",
5379                           "wbxml.public_id.known",
5380                           FT_UINT32, BASE_HEX,
5381                           VALS ( vals_wbxml_public_ids ), 0x00,
5382                           "WBXML Known Public Identifier (integer)", HFILL }
5383                 },
5384                 { &hf_wbxml_public_id_literal,
5385                         { "Public Identifier (literal)",
5386                           "wbxml.public_id.literal",
5387                           FT_STRING, BASE_NONE,
5388                           NULL, 0x00,
5389                           "WBXML Literal Public Identifier (text string)", HFILL }
5390                 },
5391                 { &hf_wbxml_charset,
5392                         { "Character Set",
5393                           "wbxml.charset",
5394                           FT_UINT32, BASE_HEX,
5395                           VALS ( vals_character_sets ), 0x00,
5396                           "WBXML Character Set", HFILL }
5397                 },
5398         };
5399
5400         /* Setup protocol subtree array */
5401         static gint *ett[] = {
5402                 &ett_wbxml,
5403                 &ett_wbxml_str_tbl,
5404                 &ett_wbxml_content,
5405         };
5406
5407         /* Register the protocol name and description */
5408         proto_wbxml = proto_register_protocol(
5409                         "WAP Binary XML",
5410                         "WBXML",
5411                         "wbxml"
5412         );
5413
5414         /* Required function calls to register the header fields
5415          * and subtrees used */
5416         proto_register_field_array(proto_wbxml, hf, array_length(hf));
5417         proto_register_subtree_array(ett, array_length(ett));
5418
5419         register_dissector("wbxml", dissect_wbxml, proto_wbxml);
5420 }
5421
5422
5423 void
5424 proto_reg_handoff_wbxml(void)
5425 {
5426         dissector_handle_t wbxml_handle;
5427
5428         /* Heuristic dissectors would be declared by means of:
5429          * heur_dissector_add("wsp", dissect_wbxml_heur, proto_wbxml);
5430          */
5431
5432         wbxml_handle = create_dissector_handle(dissect_wbxml, proto_wbxml);
5433
5434         /* Register the WSP content types (defined as protocol port)
5435          * for WBXML dissection.
5436          * 
5437          * See http://www.wapforum.org/wina/wsp-content-type.htm
5438          * 
5439          * As the media types for WSP and HTTP are the same, the WSP dissector
5440          * uses the same string dissector table as the HTTP protocol.
5441          */
5442
5443         /**** Well-known WBXML WSP Content-Type values ****/
5444         
5445         dissector_add_string("media_type",
5446                         "application/vnd.wap.wmlc", wbxml_handle);
5447         dissector_add_string("media_type",
5448                         "application/vnd.wap.wta-eventc", wbxml_handle);
5449         dissector_add_string("media_type",
5450                         "application/vnd.wap.wbxml", wbxml_handle);
5451         dissector_add_string("media_type",
5452                         "application/vnd.wap.sic", wbxml_handle);
5453         dissector_add_string("media_type",
5454                         "application/vnd.wap.slc", wbxml_handle);
5455         dissector_add_string("media_type",
5456                         "application/vnd.wap.coc", wbxml_handle);
5457         dissector_add_string("media_type",
5458                         "application/vnd.wap.connectivity-wbxml", wbxml_handle);
5459         dissector_add_string("media_type",
5460                         "application/vnd.wap.locc+wbxml", wbxml_handle);
5461         dissector_add_string("media_type",
5462                         "application/vnd.syncml+wbxml", wbxml_handle);
5463         dissector_add_string("media_type",
5464                         "application/vnd.syncml.dm+wbxml", wbxml_handle);
5465         dissector_add_string("media_type",
5466                         "application/vnd.oma.drm.rights+wbxml", wbxml_handle);
5467         dissector_add_string("media_type",
5468                         "application/vnd.wv.csp.wbxml", wbxml_handle);
5469
5470         /**** Registered WBXML WSP Content-Type values ****/
5471
5472         dissector_add_string("media_type",
5473                         "application/vnd.uplanet.cacheop-wbxml", wbxml_handle);
5474         dissector_add_string("media_type",
5475                         "application/vnd.uplanet.alert-wbxml", wbxml_handle);
5476         dissector_add_string("media_type",
5477                         "application/vnd.uplanet.list-wbxml", wbxml_handle);
5478         dissector_add_string("media_type",
5479                         "application/vnd.uplanet.listcmd-wbxml", wbxml_handle);
5480         dissector_add_string("media_type",
5481                         "application/vnd.uplanet.channel-wbxml", wbxml_handle);
5482         dissector_add_string("media_type",
5483                         "application/vnd.uplanet.bearer-choice-wbxml", wbxml_handle);
5484         dissector_add_string("media_type",
5485                         "application/vnd.phonecom.mmc-wbxml", wbxml_handle);
5486         dissector_add_string("media_type",
5487                         "application/vnd.nokia.syncset+wbxml", wbxml_handle);
5488
5489         /***** Content types that only have a textual representation *****/
5490         dissector_add_string("media_type",
5491                         "application/x-wap-prov.browser-bookmarks", wbxml_handle);
5492         dissector_add_string("media_type",
5493                         "application/x-wap-prov.browser-settings", wbxml_handle);
5494         /* Same as application/vnd.nokia.syncset+wbxml */
5495         dissector_add_string("media_type",
5496                         "application/x-prov.syncset+wbxml", wbxml_handle);
5497         
5498 }