Fix some Visual C++ analysis warnings.
[obnox/wireshark/wip.git] / epan / dissectors / packet-btl2cap.c
1 /* packet-btl2cap.c
2  * Routines for the Bluetooth L2CAP dissection
3  * Copyright 2002, Christoph Scholz <scholz@cs.uni-bonn.de>
4  *  From: http://affix.sourceforge.net/archive/ethereal_affix-3.patch
5  *
6  * Refactored for wireshark checkin
7  *   Ronnie Sahlberg 2006
8  *
9  * $Id$
10  *
11  * Wireshark - Network traffic analyzer
12  * By Gerald Combs <gerald@wireshark.org>
13  * Copyright 1998 Gerald Combs
14  *
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28  */
29
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33
34 #include <glib.h>
35
36 #include <epan/packet.h>
37 #include <etypes.h>
38 #include <epan/emem.h>
39 #include <epan/expert.h>
40 #include <epan/tap.h>
41 #include "packet-btsdp.h"
42 #include "packet-bthci_acl.h"
43 #include "packet-btl2cap.h"
44
45 /* Initialize the protocol and registered fields */
46 static int proto_btl2cap = -1;
47 static int hf_btl2cap_length = -1;
48 static int hf_btl2cap_cid = -1;
49 static int hf_btl2cap_payload = -1;
50 static int hf_btl2cap_command = -1;
51 static int hf_btl2cap_cmd_code = -1;
52 static int hf_btl2cap_cmd_ident = -1;
53 static int hf_btl2cap_cmd_length = -1;
54 static int hf_btl2cap_cmd_data = -1;
55 static int hf_btl2cap_psm = -1;
56 static int hf_btl2cap_psm_dynamic = -1;
57 static int hf_btl2cap_scid = -1;
58 static int hf_btl2cap_dcid = -1;
59 static int hf_btl2cap_icid = -1;
60 static int hf_btl2cap_controller = -1;
61 static int hf_btl2cap_dcontroller = -1;
62 static int hf_btl2cap_result = -1;
63 static int hf_btl2cap_move_result = -1;
64 static int hf_btl2cap_move_confirmation_result = -1;
65 static int hf_btl2cap_status = -1;
66 static int hf_btl2cap_rej_reason = -1;
67 static int hf_btl2cap_sig_mtu = -1;
68 static int hf_btl2cap_info_mtu = -1;
69 static int hf_btl2cap_info_flowcontrol = -1;
70 static int hf_btl2cap_info_retransmission = -1;
71 static int hf_btl2cap_info_bidirqos = -1;
72 static int hf_btl2cap_info_enh_retransmission = -1;
73 static int hf_btl2cap_info_streaming = -1;
74 static int hf_btl2cap_info_fcs = -1;
75 static int hf_btl2cap_info_flow_spec = -1;
76 static int hf_btl2cap_info_fixedchan = -1;
77 static int hf_btl2cap_info_fixedchans = -1;
78 static int hf_btl2cap_info_fixedchans_null = -1;
79 static int hf_btl2cap_info_fixedchans_signal = -1;
80 static int hf_btl2cap_info_fixedchans_connless = -1;
81 static int hf_btl2cap_info_fixedchans_amp_man = -1;
82 static int hf_btl2cap_info_fixedchans_amp_test = -1;
83 static int hf_btl2cap_info_window = -1;
84 static int hf_btl2cap_info_unicast = -1;
85 static int hf_btl2cap_info_type = -1;
86 static int hf_btl2cap_info_result = -1;
87 static int hf_btl2cap_continuation_flag = -1;
88 static int hf_btl2cap_configuration_result = -1;
89 static int hf_btl2cap_info_extfeatures = -1;
90 static int hf_btl2cap_option = -1;
91 static int hf_btl2cap_option_type = -1;
92 static int hf_btl2cap_option_length = -1;
93 static int hf_btl2cap_option_mtu = -1;
94 static int hf_btl2cap_option_flushTO = -1;
95 static int hf_btl2cap_option_flush_to_us = -1;
96 static int hf_btl2cap_option_flags = -1;
97 static int hf_btl2cap_option_service_type = -1;
98 static int hf_btl2cap_option_tokenrate = -1;
99 static int hf_btl2cap_option_tokenbucketsize = -1;
100 static int hf_btl2cap_option_peakbandwidth = -1;
101 static int hf_btl2cap_option_latency = -1;
102 static int hf_btl2cap_option_delayvariation = -1;
103 static int hf_btl2cap_option_retransmissionmode = -1;
104 static int hf_btl2cap_option_txwindow = -1;
105 static int hf_btl2cap_option_maxtransmit = -1;
106 static int hf_btl2cap_option_retransmittimeout = -1;
107 static int hf_btl2cap_option_monitortimeout = -1;
108 static int hf_btl2cap_option_mps = -1;
109 static int hf_btl2cap_option_fcs = -1;
110 static int hf_btl2cap_option_window = -1;
111 static int hf_btl2cap_option_identifier = -1;
112 static int hf_btl2cap_option_sdu_size = -1;
113 static int hf_btl2cap_option_sdu_arrival_time = -1;
114 static int hf_btl2cap_option_access_latency = -1;
115 static int hf_btl2cap_control = -1;
116 static int hf_btl2cap_control_sar = -1;
117 static int hf_btl2cap_control_reqseq = -1;
118 static int hf_btl2cap_control_txseq = -1;
119 static int hf_btl2cap_control_retransmissiondisable = -1;
120 static int hf_btl2cap_control_supervisory = -1;
121 static int hf_btl2cap_control_type = -1;
122 static int hf_btl2cap_fcs = -1;
123 static int hf_btl2cap_sdulength = -1;
124 static int hf_btl2cap_continuation_to = -1;
125 static int hf_btl2cap_reassembled_in = -1;
126
127 /* Initialize the subtree pointers */
128 static gint ett_btl2cap = -1;
129 static gint ett_btl2cap_cmd = -1;
130 static gint ett_btl2cap_option = -1;
131 static gint ett_btl2cap_extfeatures = -1;
132 static gint ett_btl2cap_fixedchans = -1;
133 static gint ett_btl2cap_control = -1;
134
135
136 /* Initialize dissector table */
137 static dissector_table_t l2cap_psm_dissector_table;
138 static dissector_table_t l2cap_cid_dissector_table;
139 static dissector_table_t l2cap_service_dissector_table;
140
141 /* This table maps cid values to psm values.
142  * The same table is used both for SCID and DCID.
143  * For received CIDs we mask the cid with 0x8000 in this table
144  */
145 static emem_tree_t *cid_to_psm_table = NULL;
146 static emem_tree_t *psm_to_service_table = NULL;
147
148 typedef struct _config_data_t {
149         guint8          mode;
150         guint8          txwindow;
151         emem_tree_t *start_fragments;  /* indexed by pinfo->fd->num */
152 } config_data_t;
153 typedef struct _psm_data_t {
154         guint16                 psm;
155         gboolean            local_service;
156         config_data_t   in;
157         config_data_t   out;
158 } psm_data_t;
159
160 static const value_string command_code_vals[] = {
161         { 0x01, "Command Reject" },
162         { 0x02, "Connection Request" },
163         { 0x03, "Connection Response" },
164         { 0x04, "Configure Request" },
165         { 0x05, "Configure Response" },
166         { 0x06, "Disconnect Request" },
167         { 0x07, "Disconnect Response" },
168         { 0x08, "Echo Request" },
169         { 0x09, "Echo Response" },
170         { 0x0A, "Information Request" },
171         { 0x0B, "Information Response" },
172         { 0x0C, "Create Channel Request" },
173         { 0x0D, "Create Channel Response" },
174         { 0x0E, "Move Channel Request" },
175         { 0x0F, "Move Channel Response" },
176         { 0x10, "Move Channel Confirmation" },
177         { 0x11, "Move Channel Confirmation Response" },
178         { 0, NULL }
179 };
180
181
182 static const value_string psm_vals[] = {
183         { 0x0001,       "SDP" },
184         { 0x0003,       "RFCOMM" },
185         { 0x0005,       "TCS-BIN" },
186         { 0x0007,       "TCS-BIN-CORDLESS" },
187         { 0x000F,       "BNEP" },
188         { 0x0011,       "HID-Control" },
189         { 0x0013,       "HID-Interrupt" },
190         { 0x0015,       "UPnP" },
191         { 0x0017,       "AVCTP-Control" },
192         { 0x0019,       "AVDTP" },
193         { 0x001B,       "AVCTP-Browsing" },
194         { 0x001D,       "UDI_C-Plane" },
195         { 0, NULL }
196 };
197
198
199 static const value_string result_vals[] = {
200         { 0x0000,       "Successful" },
201         { 0x0001,       "Pending" },
202         { 0x0002,       "Refused - PSM not supported" },
203         { 0x0003,       "Refused - security block" },
204         { 0x0004,       "Refused - no resources available" },
205         { 0x0005,       "Refused - Controller ID not supported" },
206         { 0, NULL }
207 };
208
209 static const value_string move_result_vals[] = {
210         { 0x0000,       "Success" },
211         { 0x0001,       "Pending" },
212         { 0x0002,       "Refused - Controller ID not supported" },
213         { 0x0003,       "Refused - New Controller ID is same as old" },
214         { 0x0004,       "Refused - Configuration not supported" },
215         { 0x0005,       "Refused - Move Channel collision" },
216         { 0x0006,       "Refused - Channel not allowed to be moved" },
217         { 0, NULL }
218 };
219
220 static const value_string move_result_confirmation_vals[] = {
221         { 0x0000,       "Success - both sides succeed" },
222         { 0x0001,       "Failure - one or both sides refuse" },
223         { 0, NULL }
224 };
225
226 static const value_string configuration_result_vals[] = {
227         { 0x0000, "Success"},
228         { 0x0001, "Failure - unacceptable parameters" },
229         { 0x0002, "Failure - reject (no reason provided)" },
230         { 0x0003, "Failure - unknown options" },
231         { 0x0004, "Pending" },
232         { 0x0005, "Failure - flow spec rejected" },
233         { 0, NULL }
234 };
235
236 static const value_string status_vals[] = {
237         { 0x0000,       "No further information available" },
238         { 0x0001,       "Authentication pending" },
239         { 0x0002,       "Authorization pending" },
240         { 0, NULL }
241 };
242
243 static const value_string reason_vals[] = {
244         { 0x0000,       "Command not understood" },
245         { 0x0001,       "Signaling MTU exceeded" },
246         { 0x0002,       "Invalid CID in request" },
247         { 0, NULL }
248 };
249
250 static const value_string info_type_vals[] = {
251         { 0x0001, "Connectionless MTU" },
252         { 0x0002, "Extended Features Mask" },
253         { 0x0003, "Fixed Channels Supported" },
254         { 0, NULL }
255 };
256
257 static const value_string info_result_vals[] = {
258         { 0x0000, "Success" },
259         { 0x0001, "Not Supported" },
260         { 0, NULL }
261 };
262
263 static const value_string option_servicetype_vals[] = {
264         { 0x00, "No traffic" },
265         { 0x01, "Best effort (Default)" },
266         { 0x02, "Guaranteed" },
267         { 0, NULL }
268 };
269
270 static const value_string option_type_vals[] = {
271         { 0x01, "Maximum Transmission Unit" },
272         { 0x02, "Flush Timeout" },
273         { 0x03, "Quality of Service" },
274         { 0x04, "Retransmission and Flow Control" },
275         { 0x05, "FCS" },
276         { 0x06, "Extended Flow Specification" },
277         { 0x07, "Extended Window Size" },
278         { 0, NULL }
279 };
280
281 static const value_string option_retransmissionmode_vals[] = {
282         { 0x00, "Basic Mode" },
283         { 0x01, "Retransmission Mode" },
284         { 0x02, "Flow Control Mode" },
285         { 0x03, "Enhanced Retransmission Mode" },
286         { 0x04, "Streaming Mode" },
287         { 0, NULL }
288 };
289
290 static const value_string control_sar_vals[] = {
291         { 0x00, "Unsegmented" },
292         { 0x01, "Start" },
293         { 0x02, "End" },
294         { 0x03, "Continuation" },
295         { 0, NULL }
296 };
297
298 static const value_string control_supervisory_vals[] = {
299         { 0x00, "RR" },
300         { 0x01, "REJ" },
301         { 0x02, "RNR" },
302         { 0x03, "SREJ" },
303         { 0, NULL }
304 };
305
306 static const value_string control_type_vals[] = {
307         { 0x00, "I-Frame" },
308         { 0x01, "S-Frame" },
309         { 0, NULL }
310 };
311
312 static const value_string option_fcs_vals[] = {
313         { 0x00, "No FCS" },
314         { 0x01, "16-bit FCS" },
315         { 0, NULL }
316 };
317
318 static const value_string ctrl_id_code_vals[] = {
319         { 0x00, "Bluetooth BR/EDR" },
320         { 0x01, "Wifi 802.11" },
321         { 0, NULL }
322 };
323
324 static int
325 dissect_comrej(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
326 {
327         guint16 reason;
328
329         reason = tvb_get_letohs(tvb, offset);
330         proto_tree_add_item(tree, hf_btl2cap_rej_reason, tvb, offset, 2, TRUE);
331         offset+=2;
332
333         switch(reason){
334         case 0x0000: /* Command not understood */
335                 break;
336
337         case 0x0001: /* Signaling MTU exceeded */
338                 proto_tree_add_item(tree, hf_btl2cap_sig_mtu, tvb, offset, 2, TRUE);
339                 offset+=2;
340                 break;
341
342         case 0x0002: /* Invalid CID in requets */
343                 proto_tree_add_item(tree, hf_btl2cap_scid, tvb, offset, 2, TRUE);
344                 offset+=2;
345
346                 proto_tree_add_item(tree, hf_btl2cap_dcid, tvb, offset, 2, TRUE);
347                 offset+=2;
348
349                 break;
350
351         default:
352                 break;
353         }
354
355         return offset;
356 }
357
358 static int
359 dissect_connrequest(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, gboolean is_ch_request)
360 {
361         guint16 scid, psm;
362         psm_data_t *psm_data;
363         const gchar *psm_str = "<NONE>";
364
365         psm=tvb_get_letohs(tvb, offset);
366         if( psm < BTL2CAP_DYNAMIC_PSM_START ) {
367                 proto_tree_add_item(tree, hf_btl2cap_psm, tvb, offset, 2, TRUE);
368                 psm_str = val_to_str(psm, psm_vals, "Unknown PSM");
369         }
370         else {
371                 guint32 *service, token;
372                 proto_item *item;
373
374                 item = proto_tree_add_item(tree, hf_btl2cap_psm_dynamic, tvb, offset, 2, TRUE);
375                 token = psm | ((pinfo->p2p_dir == P2P_DIR_RECV)?0x80000000:0x00000000);
376                 service = se_tree_lookup32(psm_to_service_table, token);
377
378                 if( service ) {
379                         psm_str = val_to_str(*service, vs_service_classes, "Unknown PSM");
380                         proto_item_append_text(item," (%s)", psm_str);
381                 }
382         }
383         offset+=2;
384
385         scid=tvb_get_letohs(tvb, offset);
386         proto_tree_add_item(tree, hf_btl2cap_scid, tvb, offset, 2, TRUE);
387         offset+=2;
388
389         if( psm_str )
390                 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s, SCID: 0x%04x)", psm_str, scid);
391         else
392                 col_append_fstr(pinfo->cinfo, COL_INFO, " (SCID: 0x%04x)", scid);
393
394         if( is_ch_request ) {
395                 proto_tree_add_item(tree, hf_btl2cap_controller, tvb, offset, 1, TRUE);
396                 offset+=1;
397         }
398
399         if (pinfo->fd->flags.visited == 0) {
400                 psm_data=se_alloc(sizeof(psm_data_t));
401                 psm_data->psm=psm;
402                 psm_data->local_service = (pinfo->p2p_dir == P2P_DIR_RECV) ? TRUE : FALSE;
403                 psm_data->in.mode=0;
404                 psm_data->in.txwindow=0;
405                 psm_data->in.start_fragments=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "bthci_l2cap fragment starts");
406                 psm_data->out.mode=0;
407                 psm_data->out.txwindow=0;
408                 psm_data->out.start_fragments=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "bthci_l2cap fragment starts");
409                 se_tree_insert32(cid_to_psm_table, scid|((pinfo->p2p_dir == P2P_DIR_RECV)?0x8000:0x0000), psm_data);
410
411         }
412         return offset;
413 }
414
415 static int
416 dissect_movechanrequest(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
417 {
418         guint16 icid;
419         guint8 ctrl_id;
420         
421         icid = tvb_get_letohs(tvb, offset);
422         proto_tree_add_item(tree, hf_btl2cap_icid, tvb, offset, 2, TRUE);
423         offset+=2;
424
425         ctrl_id = tvb_get_guint8(tvb, offset);
426         proto_tree_add_item(tree, hf_btl2cap_dcontroller, tvb, offset, 1, TRUE);
427         offset+=1;
428
429         col_append_fstr(pinfo->cinfo, COL_INFO, " (ICID: 0x%04x, move to %s)", icid, val_to_str(ctrl_id, ctrl_id_code_vals, "Unknown controller"));
430         
431         return offset;
432 }
433
434 static int
435 dissect_options(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int length, config_data_t *config_data)
436 {
437         proto_item *ti_option=NULL;
438         proto_tree *ti_option_subtree=NULL;
439         guint8 option_type, option_length;
440
441         while(length>0){
442                 option_type   = tvb_get_guint8(tvb, offset);
443                 option_length = tvb_get_guint8(tvb, offset+1);
444
445                 ti_option = proto_tree_add_none_format(tree,
446                                 hf_btl2cap_option, tvb,
447                                 offset, option_length + 2,
448                                 "Option: ");
449                 ti_option_subtree = proto_item_add_subtree(ti_option, ett_btl2cap_option);
450                 proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_type, tvb, offset, 1, TRUE);
451                 proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_length, tvb, offset+1, 1, TRUE);
452                 offset+=2;
453
454                 if(option_length>0){
455                         switch(option_type){
456                         case 0x01: /* MTU */
457                                 proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_mtu, tvb, offset, 2, TRUE);
458                                 offset+=2;
459
460                                 proto_item_append_text(ti_option, "MTU");
461                                 break;
462
463                         case 0x02: /* Flush timeout */
464                                 proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_flushTO, tvb, offset, 2, TRUE);
465                                 offset+=2;
466
467                                 proto_item_append_text(ti_option, "Flush Timeout");
468                                 break;
469
470                         case 0x03: /* QOS */
471                                 proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_flags, tvb, offset, 1, TRUE);
472                                 offset++;
473
474                                 proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_service_type, tvb, offset, 1, TRUE);
475                                 offset++;
476
477                                 proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_tokenrate, tvb, offset, 4, TRUE);
478                                 offset+=4;
479
480                                 proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_tokenbucketsize, tvb, offset, 4, TRUE);
481                                 offset+=4;
482
483                                 proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_peakbandwidth, tvb, offset, 4, TRUE);
484                                 offset+=4;
485
486                                 proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_latency, tvb, offset, 4, TRUE);
487                                 offset+=4;
488
489                                 proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_delayvariation, tvb, offset, 4, TRUE);
490                                 offset+=4;
491
492                                 proto_item_append_text(ti_option, "QOS");
493                                 break;
494
495                         case 0x04: /* Retransmission and Flow Control*/
496                                 if(config_data)
497                                 {
498                                         config_data->mode = tvb_get_guint8(tvb, offset);
499                                         config_data->txwindow = tvb_get_guint8(tvb, offset+1);
500                                 }
501                                 proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_retransmissionmode, tvb, offset, 1, TRUE);
502                                 offset++;
503
504                                 proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_txwindow, tvb, offset, 1, TRUE);
505                                 offset++;
506
507                                 proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_maxtransmit, tvb, offset, 1, TRUE);
508                                 offset++;
509
510                                 proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_retransmittimeout, tvb, offset, 2, TRUE);
511                                 offset+= 2;
512
513                                 proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_monitortimeout, tvb, offset, 2, TRUE);
514                                 offset+= 2;
515
516                                 proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_mps, tvb, offset, 2, TRUE);
517                                 offset+= 2;
518
519                                 proto_item_append_text(ti_option, "Retransmission and Flow Control");
520                                 break;
521
522                         case 0x05: /* FCS */
523                                 proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_fcs, tvb, offset, 1, TRUE);
524                                 offset+=1;
525
526                                 proto_item_append_text(ti_option, "FCS");
527                                 break;
528
529                         case 0x06: /* Extended Flow Specification */
530                                 proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_identifier, tvb, offset, 1, TRUE);
531                                 offset++;
532
533                                 proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_service_type, tvb, offset, 1, TRUE);
534                                 offset++;
535
536                                 proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_sdu_size, tvb, offset, 2, TRUE);
537                                 offset+=2;
538
539                                 proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_sdu_arrival_time, tvb, offset, 4, TRUE);
540                                 offset+=4;
541
542                                 proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_access_latency, tvb, offset, 4, TRUE);
543                                 offset+=4;
544
545                                 proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_flush_to_us, tvb, offset, 4, TRUE);
546                                 offset+=4;
547
548                                 proto_item_append_text(ti_option, "Extended Flow Specification");
549                                 break;
550
551                         case 0x07: /* Extended Window Size */
552                                 proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_window, tvb, offset, 2, TRUE);
553                                 offset+=2;
554
555                                 proto_item_append_text(ti_option, "Extended Window Size");
556                                 break;
557
558                         default:
559                                 proto_item_append_text(ti_option, "unknown");
560                                 offset+=option_length;
561                                 break;
562                         }
563                 }
564                 length -= (option_length + 2);
565         }
566         return offset;
567 }
568
569
570
571 static int
572 dissect_configrequest(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, guint16 length)
573 {
574         psm_data_t *psm_data;
575         config_data_t *config_data;
576         guint16 dcid;
577
578         dcid = tvb_get_letohs(tvb, offset);
579         psm_data=se_tree_lookup32(cid_to_psm_table, dcid|((pinfo->p2p_dir==P2P_DIR_RECV)?0x0000:0x8000));
580         proto_tree_add_item(tree, hf_btl2cap_dcid, tvb, offset, 2, TRUE);
581         offset+=2;
582
583         col_append_fstr(pinfo->cinfo, COL_INFO, " (DCID: 0x%04x)", dcid);
584                                         
585         proto_tree_add_item(tree, hf_btl2cap_continuation_flag, tvb, offset, 2, TRUE);
586         offset+=2;
587
588         if(tvb_length_remaining(tvb, offset)){
589                 if (psm_data)
590                         if(pinfo->p2p_dir==P2P_DIR_RECV)
591                                 config_data = &(psm_data->out);
592                         else
593                                 config_data = &(psm_data->in);
594                 else
595                         config_data = NULL;
596                 offset=dissect_options(tvb, offset, pinfo, tree, length - 4, config_data);
597         }
598
599         return offset;
600 }
601
602
603 static int
604 dissect_inforequest(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
605 {
606         guint16 info_type;
607         
608         info_type=tvb_get_letohs(tvb, offset);
609         proto_tree_add_item(tree, hf_btl2cap_info_type, tvb, offset, 2, TRUE);
610         offset+=2;
611
612         col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", val_to_str(info_type, info_type_vals, "Unknown type"));
613         return offset;
614 }
615
616 static int
617 dissect_inforesponse(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
618 {
619         guint16 info_type, result;
620         proto_item *ti_features=NULL;
621         proto_tree *ti_features_subtree=NULL;
622         guint32 features;
623
624         info_type=tvb_get_letohs(tvb, offset);
625         proto_tree_add_item(tree, hf_btl2cap_info_type, tvb, offset, 2, TRUE);
626         offset+=2;
627
628         result = tvb_get_letohs(tvb, offset);
629         proto_tree_add_item(tree, hf_btl2cap_info_result, tvb, offset, 2, TRUE);
630         offset+=2;
631
632         col_append_fstr(pinfo->cinfo, COL_INFO, " (%s, %s)",
633                                                 val_to_str(info_type, info_type_vals, "Unknown type"),
634                                                 val_to_str(result, info_result_vals, "Unknown result"));
635         
636         if(tvb_length_remaining(tvb, offset)) {
637                 switch(info_type){
638                 case 0x0001: /* Connectionless MTU */
639                         proto_tree_add_item(tree, hf_btl2cap_info_mtu, tvb, offset, 2, TRUE);
640                         offset+=2;
641
642                         break;
643                 case 0x0002: /* Extended Features */
644                         ti_features = proto_tree_add_none_format(tree,
645                                         hf_btl2cap_info_extfeatures, tvb,
646                                         offset, 4,
647                                         "Features: ");
648                         ti_features_subtree = proto_item_add_subtree(ti_features, ett_btl2cap_extfeatures);
649                         features = tvb_get_letohl(tvb, offset);
650                         if(features & 0x1)
651                                 proto_item_append_text(ti_features, "FlowControl ");
652                         if(features & 0x2)
653                                 proto_item_append_text(ti_features, "Retransmission ");
654                         if(features & 0x4)
655                                 proto_item_append_text(ti_features, "BiDirQOS ");
656                         if(features & 0x8)
657                                 proto_item_append_text(ti_features, "EnhRetransmission ");
658                         if(features & 0x10)
659                                 proto_item_append_text(ti_features, "Streaming ");
660                         if(features & 0x20)
661                                 proto_item_append_text(ti_features, "FCS ");
662                         if(features & 0x40)
663                                 proto_item_append_text(ti_features, "FlowSpec ");
664                         if(features & 0x80)
665                                 proto_item_append_text(ti_features, "FixedChan ");
666                         if(features & 0x100)
667                                 proto_item_append_text(ti_features, "WindowSize ");
668                         if(features & 0x200)
669                                 proto_item_append_text(ti_features, "Unicast ");
670                         proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_flowcontrol, tvb, offset, 4, TRUE);
671                         proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_retransmission, tvb, offset, 4, TRUE);
672                         proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_bidirqos, tvb, offset, 4, TRUE);
673                         proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_enh_retransmission, tvb, offset, 4, TRUE);
674                         proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_streaming, tvb, offset, 4, TRUE);
675                         proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_fcs, tvb, offset, 4, TRUE);
676                         proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_flow_spec, tvb, offset, 4, TRUE);
677                         proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_fixedchan, tvb, offset, 4, TRUE);
678                         proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_window, tvb, offset, 4, TRUE);
679                         proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_unicast, tvb, offset, 4, TRUE);
680                         offset+=4;
681
682                         break;
683
684                 case 0x0003: /* Fixed Channels Supported */
685                         ti_features = proto_tree_add_none_format(tree,
686                                         hf_btl2cap_info_fixedchans, tvb,
687                                         offset, 8,
688                                         "Fixed Channels Supported:");
689                         ti_features_subtree = proto_item_add_subtree(ti_features, ett_btl2cap_fixedchans);
690                         proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_fixedchans_null, tvb, offset, 4, TRUE);
691                         proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_fixedchans_signal, tvb, offset, 4, TRUE);
692                         proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_fixedchans_connless, tvb, offset, 4, TRUE);
693                         proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_fixedchans_amp_man, tvb, offset, 4, TRUE);
694                         offset+=4;
695                         proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_fixedchans_amp_test, tvb, offset, 4, TRUE);
696                         offset+=4;
697
698                         break;
699
700                 default:
701                         proto_tree_add_item(tree, hf_btl2cap_cmd_data, tvb, offset, -1, TRUE);
702                         offset+=tvb_length_remaining(tvb, offset);
703
704                         break;
705                 }
706         }
707
708         return offset;
709 }
710
711 static int
712 dissect_configresponse(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, guint16 length)
713 {
714         psm_data_t *psm_data;
715         config_data_t *config_data;
716         guint16 scid, result;
717
718         scid = tvb_get_letohs(tvb, offset);
719         psm_data=se_tree_lookup32(cid_to_psm_table, scid|((pinfo->p2p_dir==P2P_DIR_RECV)?0x0000:0x8000));
720         proto_tree_add_item(tree, hf_btl2cap_scid, tvb, offset, 2, TRUE);
721         offset+=2;
722
723         proto_tree_add_item(tree, hf_btl2cap_continuation_flag, tvb, offset, 2, TRUE);
724         offset+=2;
725
726         result = tvb_get_letohs(tvb, offset);
727         proto_tree_add_item(tree, hf_btl2cap_configuration_result, tvb, offset, 2, TRUE);
728         offset+=2;
729
730         col_append_fstr(pinfo->cinfo, COL_INFO, " - %s (SCID: 0x%04x)", val_to_str(result, configuration_result_vals, "Unknown"), scid);
731         
732         if(tvb_length_remaining(tvb, offset)){
733                 if (psm_data)
734                         if(pinfo->p2p_dir==P2P_DIR_RECV)
735                                 config_data = &(psm_data->out);
736                         else
737                                 config_data = &(psm_data->in);
738                 else
739                         config_data = NULL;
740                 offset=dissect_options(tvb, offset, pinfo, tree, length - 6, config_data);
741         }
742
743         return offset;
744 }
745
746 static int
747 dissect_connresponse(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
748 {
749         guint16 scid, dcid, result;
750         psm_data_t *psm_data;
751
752         dcid = tvb_get_letohs(tvb, offset);
753         proto_tree_add_item(tree, hf_btl2cap_dcid, tvb, offset, 2, TRUE);
754         offset+=2;
755
756         scid = tvb_get_letohs(tvb, offset);
757         proto_tree_add_item(tree, hf_btl2cap_scid, tvb, offset, 2, TRUE);
758         offset+=2;
759
760         result = tvb_get_letohs(tvb, offset);
761         proto_tree_add_item(tree, hf_btl2cap_result, tvb, offset, 2, TRUE);
762         offset+=2;
763
764         proto_tree_add_item(tree, hf_btl2cap_status, tvb, offset, 2, TRUE);
765         offset+=2;
766
767         if(!result) {
768                 col_append_fstr(pinfo->cinfo, COL_INFO, " - Success (SCID: 0x%04x, DCID: 0x%04x)", scid, dcid);
769         }
770         else {
771                 col_append_fstr(pinfo->cinfo, COL_INFO, " - %s (SCID: 0x%04x)", val_to_str(result, result_vals, "Unknown"), scid);
772         }
773                                         
774         if (pinfo->fd->flags.visited == 0) {
775                 if((psm_data=se_tree_lookup32(cid_to_psm_table, scid|((pinfo->p2p_dir==P2P_DIR_RECV)?0x0000:0x8000)))){
776                         se_tree_insert32(cid_to_psm_table, dcid|((pinfo->p2p_dir == P2P_DIR_RECV)?0x8000:0x0000), psm_data);
777                 }
778         }
779
780         return offset;
781 }
782
783 static int
784 dissect_chanresponse(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
785 {
786         return dissect_connresponse(tvb, offset, pinfo, tree);
787 }
788
789 static int
790 dissect_movechanresponse(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
791 {
792         guint16 icid, result;
793         
794         icid = tvb_get_letohs(tvb, offset);
795         proto_tree_add_item(tree, hf_btl2cap_icid, tvb, offset, 2, TRUE);
796         offset+=2;
797
798         result = tvb_get_letohs(tvb, offset);
799         proto_tree_add_item(tree, hf_btl2cap_move_result, tvb, offset, 2, TRUE);
800         offset+=2;
801
802         col_append_fstr(pinfo->cinfo, COL_INFO, " (ICID: 0x%04x, %s)", icid, val_to_str(result, move_result_vals, "Unknown result"));
803         
804         return offset;
805 }
806
807 static int
808 dissect_movechanconfirmation(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
809 {
810         guint16 icid, result;
811         
812         icid = tvb_get_letohs(tvb, offset);
813         proto_tree_add_item(tree, hf_btl2cap_icid, tvb, offset, 2, TRUE);
814         offset+=2;
815
816         result = tvb_get_letohs(tvb, offset);
817         proto_tree_add_item(tree, hf_btl2cap_move_confirmation_result, tvb, offset, 2, TRUE);
818         offset+=2;
819
820         col_append_fstr(pinfo->cinfo, COL_INFO, " (ICID: 0x%04x, %s)", icid, val_to_str(result, move_result_confirmation_vals, "Unknown result"));
821
822         return offset;
823 }
824
825 static int
826 dissect_movechanconfirmationresponse(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
827 {
828         guint16 icid;
829         
830         icid = tvb_get_letohs(tvb, offset);
831         proto_tree_add_item(tree, hf_btl2cap_icid, tvb, offset, 2, TRUE);
832         offset+=2;
833
834         col_append_fstr(pinfo->cinfo, COL_INFO, " (ICID: 0x%04x)", icid);
835         return offset;
836 }
837
838 static int
839 dissect_disconnrequestresponse(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
840 {
841         guint16 scid, dcid;
842
843         dcid = tvb_get_letohs(tvb, offset);
844         proto_tree_add_item(tree, hf_btl2cap_dcid, tvb, offset, 2, TRUE);
845         offset+=2;
846
847         scid = tvb_get_letohs(tvb, offset);
848         proto_tree_add_item(tree, hf_btl2cap_scid, tvb, offset, 2, TRUE);
849         offset+=2;
850
851         col_append_fstr(pinfo->cinfo, COL_INFO, " (SCID: 0x%04x, DCID: 0x%04x)", scid, dcid);
852         
853         return offset;
854 }
855
856 static void
857 dissect_b_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *btl2cap_tree, guint16 psm, gboolean local_service, guint16 length, int offset)
858 {
859         tvbuff_t *next_tvb;
860         next_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), length);
861
862         col_append_str(pinfo->cinfo, COL_INFO, "Connection oriented channel");
863
864         if(psm){
865                 proto_item *psm_item;
866                 guint32 *service =se_tree_lookup32(psm_to_service_table, (local_service<<31) | psm);
867
868                 if( psm < BTL2CAP_DYNAMIC_PSM_START ) {
869                 psm_item=proto_tree_add_uint(btl2cap_tree, hf_btl2cap_psm, tvb, offset, 0, psm);
870                 }
871                 else {
872                         psm_item=proto_tree_add_uint(btl2cap_tree, hf_btl2cap_psm_dynamic, tvb, offset, 0, psm);
873                         if( service )
874                                 proto_item_append_text(psm_item,": %s", val_to_str(*service, vs_service_classes, "Unknown service"));
875                 }
876                 PROTO_ITEM_SET_GENERATED(psm_item);
877
878                 /* call next dissector */
879                 if (!dissector_try_uint(l2cap_psm_dissector_table, (guint32) psm, next_tvb, pinfo, tree)) {
880                         /* not a known fixed PSM, try to find a registered service to a dynamic PSM */
881                         if(service != NULL && !dissector_try_uint(l2cap_service_dissector_table, *service, next_tvb, pinfo, tree)) {
882                                 /* unknown protocol. declare as data */
883                                 proto_tree_add_item(btl2cap_tree, hf_btl2cap_payload, tvb, offset, length, TRUE);
884                         }
885                 }
886                 offset+=tvb_length_remaining(tvb, offset);
887         }
888         else {
889                 proto_tree_add_item(btl2cap_tree, hf_btl2cap_payload, tvb, offset, length, TRUE);
890                 offset+=tvb_length_remaining(tvb, offset);
891         }
892 }
893
894 typedef struct _sdu_reassembly_t
895 {
896         guint8* reassembled;
897         guint8 seq;
898         guint32 first_frame;
899         guint32 last_frame;
900         guint16 tot_len;
901         int cur_off;    /* counter used by reassembly */
902 } sdu_reassembly_t;
903
904 static void
905 dissect_i_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *btl2cap_tree, psm_data_t *psm_data, guint16 length, int offset, config_data_t *config_data)
906 {
907         tvbuff_t *next_tvb = NULL;
908         guint16 control, segment;
909         guint16 sdulen;
910         proto_item* ti_control;
911         proto_tree* ti_control_subtree;
912         sdu_reassembly_t* mfp = NULL;
913         guint16 psm = (psm_data?psm_data->psm:0);
914
915         control = tvb_get_letohs(tvb, offset);
916         segment = (control & 0xC000) >> 14;
917         switch(segment)
918         {
919         case 0:
920                 col_append_str(pinfo->cinfo, COL_INFO, "[I] Unsegmented SDU");
921                 break;
922         case 1:
923                 col_append_str(pinfo->cinfo, COL_INFO, "[I] Start SDU");
924                 break;
925         case 2:
926                 col_append_str(pinfo->cinfo, COL_INFO, "[I] End SDU");
927                 break;
928         case 3:
929                 col_append_str(pinfo->cinfo, COL_INFO, "[I] Continuation SDU");
930                 break;
931         }
932         ti_control = proto_tree_add_none_format(btl2cap_tree, hf_btl2cap_control, tvb,
933                 offset, 2, "Control: %s reqseq:%d r:%d txseq:%d",
934                 val_to_str((control & 0xC000) >> 14, control_sar_vals, "unknown"),
935                 (control & 0x3F00) >> 8,
936                 (control & 0x0080) >> 7,
937                 (control & 0x007E) >> 1);
938         ti_control_subtree = proto_item_add_subtree(ti_control, ett_btl2cap_control);
939         proto_tree_add_item(ti_control_subtree, hf_btl2cap_control_sar, tvb, offset, 2, TRUE);
940         proto_tree_add_item(ti_control_subtree, hf_btl2cap_control_reqseq, tvb, offset, 2, TRUE);
941         proto_tree_add_item(ti_control_subtree, hf_btl2cap_control_retransmissiondisable, tvb, offset, 2, TRUE);
942         proto_tree_add_item(ti_control_subtree, hf_btl2cap_control_txseq, tvb, offset, 2, TRUE);
943         proto_tree_add_item(ti_control_subtree, hf_btl2cap_control_type, tvb, offset, 2, TRUE);
944         offset += 2;
945
946         /*Segmented frames with SAR = start have an extra SDU length header field*/
947         if(segment == 0x01) {
948                 proto_item *pi;
949                 sdulen = tvb_get_letohs(tvb, offset);
950                 pi = proto_tree_add_item(btl2cap_tree, hf_btl2cap_sdulength, tvb, offset, 2, TRUE);
951                 offset += 2;
952                 length -= 6; /*Control, SDUlength, FCS*/
953
954                 /* Detect malformed data */
955                 if (sdulen < length) {
956                         sdulen = length;
957                         expert_add_info_format(pinfo, pi, PI_MALFORMED, PI_WARN,
958                                         "SDU length less than length of first packet");
959                 }
960
961                 if(!pinfo->fd->flags.visited){
962                         mfp=se_alloc(sizeof(sdu_reassembly_t));
963                         mfp->first_frame=pinfo->fd->num;
964                         mfp->last_frame=0;
965                         mfp->tot_len=sdulen;
966                         mfp->reassembled=se_alloc(sdulen);
967                         tvb_memcpy(tvb, mfp->reassembled, offset, length);
968                         mfp->cur_off=length;
969                         se_tree_insert32(config_data->start_fragments, pinfo->fd->num, mfp);
970                 } else {
971                         mfp=se_tree_lookup32(config_data->start_fragments, pinfo->fd->num);
972                 }
973                 if(mfp != NULL && mfp->last_frame){
974                         proto_item *item;
975                         item=proto_tree_add_uint(btl2cap_tree, hf_btl2cap_reassembled_in, tvb, 0, 0, mfp->last_frame);
976                         PROTO_ITEM_SET_GENERATED(item);
977                         col_append_fstr(pinfo->cinfo, COL_INFO, "[Reassembled in #%u] ", mfp->last_frame);
978                 }
979         } else {
980                 length -= 4; /*Control, FCS*/
981         }
982         if(segment == 0x02 || segment == 0x03) {
983                 mfp=se_tree_lookup32_le(config_data->start_fragments, pinfo->fd->num);
984                 if(!pinfo->fd->flags.visited){
985                         if(mfp != NULL && !mfp->last_frame && (mfp->tot_len>=mfp->cur_off+length)){
986                                 tvb_memcpy(tvb, mfp->reassembled+mfp->cur_off, offset, length);
987                                 mfp->cur_off+=length;
988                                 if(segment == 0x02){
989                                         mfp->last_frame=pinfo->fd->num;
990                                 }
991                         }
992                 }
993                 if(mfp){
994                         proto_item *item;
995                         item=proto_tree_add_uint(btl2cap_tree, hf_btl2cap_continuation_to, tvb, 0, 0, mfp->first_frame);
996                         PROTO_ITEM_SET_GENERATED(item);
997                         col_append_fstr(pinfo->cinfo, COL_INFO, "[Continuation to #%u] ", mfp->first_frame);
998                 }
999         }
1000         if(segment == 0x02 && mfp != NULL && mfp->last_frame==pinfo->fd->num){
1001                 next_tvb = tvb_new_child_real_data(tvb, (guint8*)mfp->reassembled, mfp->tot_len, mfp->tot_len);
1002                 add_new_data_source(pinfo, next_tvb, "Reassembled L2CAP");
1003         }
1004         /*pass up to higher layer if we have a complete packet*/
1005         if(segment == 0x00) {
1006                 next_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset) - 2, length);
1007         }
1008         if(next_tvb) {
1009                 if(psm){
1010                         guint32 *service =se_tree_lookup32(psm_to_service_table, ((psm_data?psm_data->local_service:0)<<31) | psm);
1011                         proto_item *psm_item;
1012
1013                         if( psm < BTL2CAP_DYNAMIC_PSM_START ) {
1014                         psm_item=proto_tree_add_uint(btl2cap_tree, hf_btl2cap_psm, tvb, offset, 0, psm);
1015                         }
1016                         else {
1017                                 psm_item=proto_tree_add_uint(btl2cap_tree, hf_btl2cap_psm_dynamic, tvb, offset, 0, psm);
1018                                 if(service)
1019                                         proto_item_append_text(psm_item," (%s)", val_to_str(*service, vs_service_classes, "Unknown service"));
1020                         }
1021                         PROTO_ITEM_SET_GENERATED(psm_item);
1022
1023                         /* call next dissector */
1024                         if (!dissector_try_uint(l2cap_psm_dissector_table, (guint32) psm, next_tvb, pinfo, tree)) {
1025                                 /* not a known fixed PSM, try to find a registered service to a dynamic PSM */
1026                                 if(service != NULL && !dissector_try_uint(l2cap_service_dissector_table, *service, next_tvb, pinfo, tree)) {
1027                                         /* unknown protocol. declare as data */
1028                                         proto_tree_add_item(btl2cap_tree, hf_btl2cap_payload, next_tvb, 0, tvb_length(next_tvb), TRUE);
1029                                 }
1030                         }
1031                 }
1032                 else {
1033                         proto_tree_add_item(btl2cap_tree, hf_btl2cap_payload, next_tvb, 0, tvb_length(next_tvb), TRUE);
1034                 }
1035         }
1036         offset+=(tvb_length_remaining(tvb, offset) - 2);
1037         proto_tree_add_item(btl2cap_tree, hf_btl2cap_fcs, tvb, offset, 2, TRUE);
1038         offset += 2;
1039 }
1040
1041 static void
1042 dissect_s_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, proto_tree *btl2cap_tree, guint16 psm _U_, guint16 length _U_, int offset, config_data_t *config_data _U_)
1043 {
1044         proto_item* ti_control;
1045         proto_tree* ti_control_subtree;
1046         guint16 control;
1047
1048         control = tvb_get_letohs(tvb, offset);
1049         switch((control & 0x000C) >> 2)
1050         {
1051         case 0:
1052                 col_append_str(pinfo->cinfo, COL_INFO, "[S] Receiver Ready");
1053                 break;
1054         case 1:
1055                 col_append_str(pinfo->cinfo, COL_INFO, "[S] Reject");
1056                 break;
1057         default:
1058                 col_append_str(pinfo->cinfo, COL_INFO, "[S] Unknown supervisory frame");
1059                 break;
1060         }
1061         ti_control = proto_tree_add_none_format(btl2cap_tree, hf_btl2cap_control, tvb,
1062                 offset, 2, "Control: %s reqseq:%d r:%d",
1063                 val_to_str((control & 0x000C) >> 2, control_supervisory_vals, "unknown"),
1064                 (control & 0x3F00) >> 8,
1065                 (control & 0x0080) >> 7);
1066         ti_control_subtree = proto_item_add_subtree(ti_control, ett_btl2cap_control);
1067         proto_tree_add_item(ti_control_subtree, hf_btl2cap_control_reqseq, tvb, offset, 2, TRUE);
1068         proto_tree_add_item(ti_control_subtree, hf_btl2cap_control_retransmissiondisable, tvb, offset, 2, TRUE);
1069         proto_tree_add_item(ti_control_subtree, hf_btl2cap_control_supervisory, tvb, offset, 2, TRUE);
1070         proto_tree_add_item(ti_control_subtree, hf_btl2cap_control_type, tvb, offset, 2, TRUE);
1071         offset += 2;
1072         proto_tree_add_item(ti_control_subtree, hf_btl2cap_fcs, tvb, offset, 2, TRUE);
1073         offset += 2;
1074 }
1075
1076 /* Code to actually dissect the packets
1077  * This dissector will only be called ontop of BTHCI ACL
1078  * and this dissector _REQUIRES_ that
1079  * pinfo->private_data points to a valid bthci_acl_data_t structure
1080  */
1081 static void
1082 dissect_btl2cap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1083 {
1084         int offset=0;
1085         proto_item *ti=NULL;
1086         proto_tree *btl2cap_tree=NULL;
1087         guint16 length, cid;
1088         guint16 psm;
1089         guint16 control;
1090         tvbuff_t *next_tvb = NULL;
1091         psm_data_t *psm_data;
1092         bthci_acl_data_t *acl_data;
1093         btl2cap_data_t *l2cap_data;
1094         config_data_t *config_data;
1095         void* pd_save;
1096
1097         col_set_str(pinfo->cinfo, COL_PROTOCOL, "L2CAP");
1098         switch (pinfo->p2p_dir) {
1099
1100         case P2P_DIR_SENT:
1101                 col_add_str(pinfo->cinfo, COL_INFO, "Sent ");
1102                 break;
1103
1104         case P2P_DIR_RECV:
1105                 col_add_str(pinfo->cinfo, COL_INFO, "Rcvd ");
1106                 break;
1107
1108         case P2P_DIR_UNKNOWN:
1109                 col_clear(pinfo->cinfo, COL_INFO);
1110                 break;
1111
1112         default:
1113                 col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown direction %d ",
1114                     pinfo->p2p_dir);
1115                 break;
1116         }
1117
1118         if(tree){
1119                 ti=proto_tree_add_item(tree, proto_btl2cap, tvb, offset, -1, FALSE);
1120                 btl2cap_tree=proto_item_add_subtree(ti, ett_btl2cap);
1121         }
1122
1123         length = tvb_get_letohs(tvb, offset);
1124         proto_tree_add_item(btl2cap_tree, hf_btl2cap_length, tvb, offset, 2, TRUE);
1125         offset+=2;
1126
1127         cid = tvb_get_letohs(tvb, offset);
1128         proto_tree_add_item(btl2cap_tree, hf_btl2cap_cid, tvb, offset, 2, TRUE);
1129         offset+=2;
1130
1131         acl_data=(bthci_acl_data_t *)pinfo->private_data;
1132         l2cap_data=ep_alloc(sizeof(btl2cap_data_t));
1133         l2cap_data->chandle=acl_data->chandle;
1134         l2cap_data->cid=cid;
1135         pd_save = pinfo->private_data;
1136         pinfo->private_data=l2cap_data;
1137
1138         if(cid==BTL2CAP_FIXED_CID_SIGNAL){ /* This is a command packet*/
1139                 while(offset<(length+4)) {
1140                         proto_tree *btl2cap_cmd_tree=NULL;
1141                         proto_item *ti_command=NULL;
1142                         guint8 cmd_code;
1143                         guint16 cmd_length;
1144                         const gchar *cmd_str;
1145
1146                         ti_command=proto_tree_add_none_format(btl2cap_tree,
1147                                         hf_btl2cap_command, tvb,
1148                                         offset, length,
1149                                         "Command: ");
1150                         btl2cap_cmd_tree=proto_item_add_subtree(ti_command, ett_btl2cap_cmd);
1151
1152                         cmd_code=tvb_get_guint8(tvb, offset);
1153                         proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_cmd_code, tvb, offset, 1, TRUE);
1154                         offset++;
1155
1156                         proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_cmd_ident, tvb, offset, 1, TRUE);
1157                         offset++;
1158
1159                         cmd_length=tvb_get_letohs(tvb, offset);
1160                         proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_cmd_length, tvb, offset, 2, TRUE);
1161                         proto_item_set_len(ti_command, cmd_length+4);
1162                         offset+=2;
1163
1164                         cmd_str = val_to_str(cmd_code, command_code_vals, "Unknown cmd");
1165                         proto_item_append_text(ti_command,"%s", cmd_str);
1166                         col_append_fstr(pinfo->cinfo, COL_INFO, "%s", cmd_str);
1167                         
1168                         switch(cmd_code) {
1169                         case 0x01: /* Command Reject */
1170                                 offset=dissect_comrej(tvb, offset, pinfo, btl2cap_cmd_tree);
1171                                 break;
1172
1173                         case 0x02: /* Connection Request */
1174                                 offset=dissect_connrequest(tvb, offset, pinfo, btl2cap_cmd_tree, FALSE);
1175                                 break;
1176
1177                         case 0x03: /* Connection Response */
1178                                 offset=dissect_connresponse(tvb, offset, pinfo, btl2cap_cmd_tree);
1179                                 break;
1180
1181                         case 0x04: /* Configure Request */
1182                                 offset=dissect_configrequest(tvb, offset, pinfo, btl2cap_cmd_tree, cmd_length);
1183                                 break;
1184
1185                         case 0x05: /* Configure Response */
1186                                 offset=dissect_configresponse(tvb, offset, pinfo, btl2cap_cmd_tree, cmd_length);
1187                                 break;
1188
1189                         case 0x06: /* Disconnect Request */
1190                                 offset=dissect_disconnrequestresponse(tvb, offset, pinfo, btl2cap_cmd_tree);
1191                                 break;
1192
1193                         case 0x07: /* Disconnect Response */
1194                                 offset=dissect_disconnrequestresponse(tvb, offset, pinfo, btl2cap_cmd_tree);
1195                                 break;
1196
1197                         case 0x08: /* Echo Request */
1198                                 offset+=tvb_length_remaining(tvb, offset);
1199                                 break;
1200
1201                         case 0x09: /* Echo Response */
1202                                 offset+=tvb_length_remaining(tvb, offset);
1203                                 break;
1204
1205                         case 0x0a: /* Information Request */
1206                                 offset=dissect_inforequest(tvb, offset, pinfo, btl2cap_cmd_tree);
1207                                 break;
1208
1209                         case 0x0b: /* Information Response */
1210                                 offset=dissect_inforesponse(tvb, offset, pinfo, btl2cap_cmd_tree);
1211                                 break;
1212
1213                         case 0x0c: /* Create Channel Request */
1214                                 offset=dissect_connrequest(tvb, offset, pinfo, btl2cap_cmd_tree, TRUE);
1215                                 break;
1216
1217                         case 0x0d: /* Create Channel Response */
1218                                 offset=dissect_chanresponse(tvb, offset, pinfo, btl2cap_cmd_tree);
1219                                 break;
1220
1221                         case 0x0e: /* Move Channel Request */
1222                                 offset=dissect_movechanrequest(tvb, offset, pinfo, btl2cap_cmd_tree);
1223                                 break;
1224
1225                         case 0x0f: /* Move Channel Response */
1226                                 offset=dissect_movechanresponse(tvb, offset, pinfo, btl2cap_cmd_tree);
1227                                 break;
1228
1229                         case 0x10: /* Move Channel Confirmation */
1230                                 offset=dissect_movechanconfirmation(tvb, offset, pinfo, btl2cap_cmd_tree);
1231                                 break;
1232
1233                         case 0x11: /* Move Channel Confirmation Response */
1234                                 offset=dissect_movechanconfirmationresponse(tvb, offset, pinfo, btl2cap_cmd_tree);
1235                                 break;
1236
1237                         default:
1238                                 proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_cmd_data, tvb, offset, -1, TRUE);
1239                                 offset+=tvb_length_remaining(tvb, offset);
1240                                 break;
1241                         }
1242                 }
1243         }
1244         else if (cid == BTL2CAP_FIXED_CID_CONNLESS) { /* Connectionless reception channel */
1245                 col_append_str(pinfo->cinfo, COL_INFO, "Connectionless reception channel");
1246
1247                 psm = tvb_get_letohs(tvb, offset);
1248                 proto_tree_add_item(btl2cap_tree, hf_btl2cap_psm, tvb, offset, 2, TRUE);
1249                 offset+=2;
1250
1251                 next_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), length);
1252
1253                 /* call next dissector */
1254                 if(!dissector_try_uint(l2cap_psm_dissector_table, (guint32) psm, next_tvb, pinfo, tree)) {
1255                         /* not a known fixed PSM, try to find a registered service to a dynamic PSM */
1256                         guint32 *service;
1257                         service=se_tree_lookup32(psm_to_service_table, ((pinfo->p2p_dir==P2P_DIR_RECV)?0x80000000:0) | psm);
1258                         
1259                         if(!service || !dissector_try_uint(l2cap_service_dissector_table, *service,     next_tvb, pinfo, tree)) {
1260                                 /* unknown protocol. declare as data */
1261                                 proto_tree_add_item(btl2cap_tree, hf_btl2cap_payload, tvb, offset, length, TRUE);
1262                         }
1263                 }
1264                 offset+=tvb_length_remaining(tvb, offset);
1265         }
1266         else if(cid < BTL2CAP_FIXED_CID_MAX) {
1267                 if (cid == BTL2CAP_FIXED_CID_AMP_MAN) {
1268                         control = tvb_get_letohs(tvb, offset);
1269                         if(control & 0x1) {
1270                                 dissect_s_frame(tvb, pinfo, tree, btl2cap_tree, 0 /* unused */, length, offset, NULL /* unused */);
1271                         } else {
1272                                 proto_item* ti_control;
1273                                 proto_tree* ti_control_subtree;
1274
1275                                 ti_control = proto_tree_add_none_format(btl2cap_tree, hf_btl2cap_control, tvb,
1276                                         offset, 2, "Control: %s reqseq:%d r:%d txseq:%d",
1277                                         val_to_str((control & 0xC000) >> 14, control_sar_vals, "unknown"),
1278                                         (control & 0x3F00) >> 8,
1279                                         (control & 0x0080) >> 7,
1280                                         (control & 0x007E) >> 1);
1281                                 ti_control_subtree = proto_item_add_subtree(ti_control, ett_btl2cap_control);
1282                                 proto_tree_add_item(ti_control_subtree, hf_btl2cap_control_sar, tvb, offset, 2, TRUE);
1283                                 proto_tree_add_item(ti_control_subtree, hf_btl2cap_control_reqseq, tvb, offset, 2, TRUE);
1284                                 proto_tree_add_item(ti_control_subtree, hf_btl2cap_control_retransmissiondisable, tvb, offset, 2, TRUE);
1285                                 proto_tree_add_item(ti_control_subtree, hf_btl2cap_control_txseq, tvb, offset, 2, TRUE);
1286                                 proto_tree_add_item(ti_control_subtree, hf_btl2cap_control_type, tvb, offset, 2, TRUE);
1287                                 offset += 2;
1288                                 proto_tree_add_item(btl2cap_tree, hf_btl2cap_fcs, tvb, tvb_length(tvb)-2, 2, TRUE);
1289
1290                                 next_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset)-2, length);
1291                         }
1292                 }
1293                 else {
1294                         next_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), length);
1295                 }
1296                 /* call next dissector */
1297                 if(next_tvb && !dissector_try_uint(l2cap_cid_dissector_table, (guint32) cid,
1298                                         next_tvb, pinfo, tree)){
1299                         /* unknown protocol. declare as data */
1300                         proto_tree_add_item(btl2cap_tree, hf_btl2cap_payload, tvb, offset, length, TRUE);
1301                 }
1302         }
1303         else /* if(cid >= BTL2CAP_FIXED_CID_MAX) */ { /* Connection oriented channel */
1304                 if((psm_data=se_tree_lookup32(cid_to_psm_table, cid|((pinfo->p2p_dir==P2P_DIR_RECV)?0x0000:0x8000)))){
1305                         psm=psm_data->psm;
1306                         if(pinfo->p2p_dir==P2P_DIR_RECV)
1307                                 config_data = &(psm_data->in);
1308                         else
1309                                 config_data = &(psm_data->out);
1310                         if(config_data->mode == 0) {
1311                                 dissect_b_frame(tvb, pinfo, tree, btl2cap_tree, psm, psm_data->local_service, length, offset);
1312                         } else {
1313                                 control = tvb_get_letohs(tvb, offset);
1314                                 if(control & 0x1) {
1315                                         dissect_s_frame(tvb, pinfo, tree, btl2cap_tree, psm, length, offset, config_data);
1316                                 } else {
1317                                         dissect_i_frame(tvb, pinfo, tree, btl2cap_tree, psm_data, length, offset, config_data);
1318                                 }
1319                         }
1320                 } else {
1321                         psm=0;
1322                         dissect_b_frame(tvb, pinfo, tree, btl2cap_tree, psm, FALSE, length, offset);
1323                 }
1324         }
1325         pinfo->private_data = pd_save;
1326 }
1327
1328
1329 static int
1330 btl2cap_sdp_tap_packet(void *arg _U_, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *arg2)
1331 {
1332         btsdp_data_t *sdp_data = (btsdp_data_t *) arg2;
1333
1334         if( sdp_data->protocol == BTSDP_L2CAP_PROTOCOL_UUID ) {
1335                 guint32 token, *psm_service;
1336
1337                 token = sdp_data->channel | ((sdp_data->flags & BTSDP_LOCAL_SERVICE_FLAG_MASK)<<31);
1338
1339                 psm_service=se_tree_lookup32(psm_to_service_table, token);
1340                 if(!psm_service){
1341                         psm_service=se_alloc0(sizeof(guint32));
1342                         se_tree_insert32(psm_to_service_table, token, psm_service);
1343                 }
1344                 *psm_service = sdp_data->service;
1345         }
1346         return 0;
1347 }
1348
1349
1350 /* Register the protocol with Wireshark */
1351 void
1352 proto_register_btl2cap(void)
1353 {
1354
1355         /* Setup list of header fields  See Section 1.6.1 for details*/
1356         static hf_register_info hf[] = {
1357                 { &hf_btl2cap_length,
1358                         { "Length",           "btl2cap.length",
1359                                 FT_UINT16, BASE_DEC, NULL, 0x0,
1360                                 "L2CAP Payload Length", HFILL }
1361                 },
1362                 { &hf_btl2cap_cid,
1363                         { "CID",           "btl2cap.cid",
1364                                 FT_UINT16, BASE_HEX, NULL, 0x0,
1365                                 "L2CAP Channel Identifier", HFILL }
1366                 },
1367                 { &hf_btl2cap_payload,
1368                         { "Payload",           "btl2cap.payload",
1369                                 FT_BYTES, BASE_NONE, NULL, 0x0,
1370                                 "L2CAP Payload", HFILL }
1371                 },
1372                 { &hf_btl2cap_command,
1373                         { "Command",           "btl2cap.command",
1374                                 FT_NONE, BASE_NONE, NULL, 0x0,
1375                                 "L2CAP Command", HFILL }
1376                 },
1377                 { &hf_btl2cap_cmd_code,
1378                         { "Command Code",           "btl2cap.cmd_code",
1379                                 FT_UINT8, BASE_HEX, VALS(command_code_vals), 0x0,
1380                                 "L2CAP Command Code", HFILL }
1381                 },
1382                 { &hf_btl2cap_cmd_ident,
1383                         { "Command Identifier",           "btl2cap.cmd_ident",
1384                                 FT_UINT8, BASE_HEX, NULL, 0x0,
1385                                 "L2CAP Command Identifier", HFILL }
1386                 },
1387                 { &hf_btl2cap_cmd_length,
1388                         { "Command Length",           "btl2cap.cmd_length",
1389                                 FT_UINT8, BASE_DEC, NULL, 0x0,
1390                                 "L2CAP Command Length", HFILL }
1391                 },
1392                 { &hf_btl2cap_cmd_data,
1393                         { "Command Data",           "btl2cap.cmd_data",
1394                                 FT_NONE, BASE_NONE, NULL, 0x0,
1395                                 "L2CAP Command Data", HFILL }
1396                 },
1397                 { &hf_btl2cap_psm,
1398                         { "PSM",           "btl2cap.psm",
1399                                 FT_UINT16, BASE_HEX, VALS(psm_vals), 0x0,
1400                                 "Protocol/Service Multiplexer", HFILL }
1401                 },
1402                 { &hf_btl2cap_psm_dynamic,
1403                         { "Dynamic PSM",           "btl2cap.psm",
1404                                 FT_UINT16, BASE_HEX, NULL, 0x0,          
1405                                 "Dynamic Protocol/Service Multiplexer", HFILL }
1406                 },
1407                 { &hf_btl2cap_scid,
1408                         { "Source CID",           "btl2cap.scid",
1409                                 FT_UINT16, BASE_HEX, NULL, 0x0,
1410                                 "Source Channel Identifier", HFILL }
1411                 },
1412                 { &hf_btl2cap_dcid,
1413                         { "Destination CID",           "btl2cap.dcid",
1414                                 FT_UINT16, BASE_HEX, NULL, 0x0,
1415                                 "Destination Channel Identifier", HFILL }
1416                 },
1417                 { &hf_btl2cap_icid,
1418                         { "Initiator CID",                       "btl2cap.icid",
1419                                 FT_UINT16, BASE_HEX, NULL, 0x0,
1420                                 "Initiator Channel Identifier", HFILL }
1421                 },
1422                 { &hf_btl2cap_controller,
1423                         { "Controller ID",                       "btl2cap.ctrl_id",
1424                                 FT_UINT8, BASE_DEC, VALS(ctrl_id_code_vals), 0x0,
1425                                 NULL, HFILL }
1426                 },
1427                 { &hf_btl2cap_dcontroller,
1428                         { "Controller ID",                       "btl2cap.dctrl_id",
1429                                 FT_UINT8, BASE_DEC, VALS(ctrl_id_code_vals), 0x0,
1430                                 "Destination Controller ID", HFILL }
1431                 },
1432                 { &hf_btl2cap_result,
1433                         { "Result",           "btl2cap.result",
1434                                 FT_UINT16, BASE_HEX, VALS(result_vals), 0x0,
1435                                 NULL, HFILL }
1436                 },
1437                 { &hf_btl2cap_move_result,
1438                         { "Move Result",                   "btl2cap.move_result",
1439                                 FT_UINT16, BASE_HEX, VALS(move_result_vals), 0x0,
1440                                 NULL, HFILL }
1441                 },
1442                 { &hf_btl2cap_move_confirmation_result,
1443                         { "Move Result",                   "btl2cap.move_result",
1444                                 FT_UINT16, BASE_HEX, VALS(move_result_confirmation_vals), 0x0,
1445                                 NULL, HFILL }
1446                 },
1447                 { &hf_btl2cap_status,
1448                         { "Status",           "btl2cap.status",
1449                                 FT_UINT16, BASE_HEX, VALS(status_vals), 0x0,
1450                                 NULL, HFILL }
1451                 },
1452                 { &hf_btl2cap_rej_reason,
1453                         { "Reason",           "btl2cap.rej_reason",
1454                                 FT_UINT16, BASE_HEX, VALS(reason_vals), 0x0,
1455                                 NULL, HFILL }
1456                 },
1457                 { &hf_btl2cap_sig_mtu,
1458                         { "Maximum Signalling MTU",           "btl2cap.sig_mtu",
1459                                 FT_UINT16, BASE_DEC, NULL, 0x0,
1460                                 NULL, HFILL }
1461                 },
1462                 { &hf_btl2cap_info_mtu,
1463                         { "Remote Entity MTU",           "btl2cap.info_mtu",
1464                                 FT_UINT16, BASE_DEC, NULL, 0x0,
1465                                 "Remote entity acceptable connectionless MTU", HFILL }
1466                 },
1467                 { &hf_btl2cap_info_flowcontrol,
1468                         { "Flow Control Mode",           "btl2cap.info_flowcontrol",
1469                                 FT_UINT8, BASE_DEC, NULL, 0x01,
1470                                 "Flow Control mode support", HFILL }
1471                 },
1472                 { &hf_btl2cap_info_retransmission,
1473                         { "Retransmission Mode",         "btl2cap.info_retransmission",
1474                                 FT_UINT8, BASE_DEC, NULL, 0x02,
1475                                 "Retransmission mode support", HFILL }
1476                 },
1477                 { &hf_btl2cap_info_bidirqos,
1478                         { "Bi-Directional QOS",          "btl2cap.info_bidirqos",
1479                                 FT_UINT8, BASE_DEC, NULL, 0x04,
1480                                 "Bi-Directional QOS support", HFILL }
1481                 },
1482                 { &hf_btl2cap_info_enh_retransmission,
1483                         { "Enhancded Retransmission Mode", "btl2cap.info_enh_retransmission",
1484                                 FT_UINT8, BASE_DEC, NULL, 0x08,
1485                                 "Enhancded Retransmission mode support", HFILL }
1486                 },
1487                 { &hf_btl2cap_info_streaming,
1488                         { "Streaming Mode", "btl2cap.info_streaming",
1489                                 FT_UINT8, BASE_DEC, NULL, 0x10,
1490                                 "Streaming mode support", HFILL }
1491                 },
1492                 { &hf_btl2cap_info_fcs,
1493                         { "FCS", "btl2cap.info_fcs",
1494                                 FT_UINT8, BASE_DEC, NULL, 0x20,
1495                                 "FCS support", HFILL }
1496                 },
1497                 { &hf_btl2cap_info_flow_spec,
1498                         { "Extended Flow Specification for BR/EDR", "btl2cap.info_flow_spec",
1499                                 FT_UINT8, BASE_DEC, NULL, 0x40,
1500                                 "Extended Flow Specification for BR/EDR support", HFILL }
1501                 },
1502                 { &hf_btl2cap_info_fixedchan,
1503                         { "Fixed Channels", "btl2cap.info_fixedchan",
1504                                 FT_UINT8, BASE_DEC, NULL, 0x80,
1505                                 "Fixed Channels support", HFILL }
1506                 },
1507                 { &hf_btl2cap_info_window,
1508                         { "Extended Window Size", "btl2cap.info_window",
1509                                 FT_UINT8, BASE_DEC, NULL, 0x01,
1510                                 "Extended Window Size support", HFILL }
1511                 },
1512                 { &hf_btl2cap_info_unicast,
1513                         { "Unicast Connectionless Data Reception", "btl2cap.info_unicast",
1514                                 FT_UINT8, BASE_DEC, NULL, 0x02,
1515                                 "Unicast Connectionless Data Reception support", HFILL }
1516                 },
1517                 { &hf_btl2cap_info_fixedchans,
1518                         { "Fixed Channels", "btl2cap.info_fixedchans",
1519                                 FT_NONE, BASE_NONE, NULL, 0x0,
1520                                 NULL, HFILL }
1521                 },
1522                 { &hf_btl2cap_info_fixedchans_null,
1523                         { "Null identifier", "btl2cap.info_fixedchans_null",
1524                                 FT_UINT32, BASE_DEC, NULL, 0x1,
1525                                 NULL, HFILL }
1526                 },
1527                 { &hf_btl2cap_info_fixedchans_signal,
1528                         { "L2CAP signaling channel", "btl2cap.info_fixedchans_signal",
1529                                 FT_UINT32, BASE_DEC, NULL, 0x2,
1530                                 NULL, HFILL }
1531                 },
1532                 { &hf_btl2cap_info_fixedchans_connless,
1533                         { "Connectionless reception", "btl2cap.info_fixedchans_connless",
1534                                 FT_UINT32, BASE_DEC, NULL, 0x4,
1535                                 NULL, HFILL }
1536                 },
1537                 { &hf_btl2cap_info_fixedchans_amp_man,
1538                         { "AMP Manager protocol", "btl2cap.info_fixedchans_amp_man",
1539                                 FT_UINT32, BASE_DEC, NULL, 0x8,
1540                                 NULL, HFILL }
1541                 },
1542                 { &hf_btl2cap_info_fixedchans_amp_test,
1543                         { "AMP Test Manager", "btl2cap.info_fixedchans_amp_test",
1544                                 FT_UINT32, BASE_DEC, NULL, 0x80000000,
1545                                 NULL, HFILL }
1546                 },
1547                 { &hf_btl2cap_info_type,
1548                         { "Information Type",           "btl2cap.info_type",
1549                                 FT_UINT16, BASE_HEX, VALS(info_type_vals), 0x0,
1550                                 "Type of implementation-specific information", HFILL }
1551                 },
1552                 { &hf_btl2cap_info_result,
1553                         { "Result",           "btl2cap.info_result",
1554                                 FT_UINT16, BASE_HEX, VALS(info_result_vals), 0x0,
1555                                 "Information about the success of the request", HFILL }
1556                 },
1557                 { &hf_btl2cap_info_extfeatures,
1558                         { "Extended Features",           "btl2cap.info_extfeatures",
1559                                 FT_NONE, BASE_NONE, NULL, 0x0,
1560                                 "Extended Features Mask", HFILL }
1561                 },
1562                 { &hf_btl2cap_continuation_flag,
1563                         { "Continuation Flag",           "btl2cap.continuation",
1564                                 FT_BOOLEAN, 16, NULL, 0x0001,
1565                                 NULL, HFILL }
1566                 },
1567                 { &hf_btl2cap_configuration_result,
1568                         { "Result",           "btl2cap.conf_result",
1569                                 FT_UINT16, BASE_HEX, VALS(configuration_result_vals), 0x0,
1570                                 "Configuration Result", HFILL }
1571                 },
1572                 { &hf_btl2cap_option_type,
1573                         { "Type",           "btl2cap.option_type",
1574                                 FT_UINT8, BASE_HEX, VALS(option_type_vals), 0x0,
1575                                 "Type of option", HFILL }
1576                 },
1577                 { &hf_btl2cap_option_length,
1578                         { "Length",           "btl2cap.option_length",
1579                                 FT_UINT8, BASE_DEC, NULL, 0x0,
1580                                 "Number of octets in option payload", HFILL }
1581                 },
1582                 { &hf_btl2cap_option_mtu,
1583                         { "MTU",           "btl2cap.option_mtu",
1584                                 FT_UINT16, BASE_DEC, NULL, 0x0,
1585                                 "Maximum Transmission Unit", HFILL }
1586                 },
1587                 { &hf_btl2cap_option_flushTO,
1588                         { "Flush Timeout (ms)",           "btl2cap.option_flushto",
1589                                 FT_UINT16, BASE_DEC, NULL, 0x0,
1590                                 "Flush Timeout in milliseconds", HFILL }
1591                 },
1592                 { &hf_btl2cap_option_flush_to_us,
1593                         { "Flush Timeout (us)",                   "btl2cap.option_flushto",
1594                                 FT_UINT32, BASE_DEC, NULL, 0x0,
1595                                 "Flush Timeout (microseconds)", HFILL }
1596                 },
1597                 { &hf_btl2cap_option_sdu_size,
1598                         { "Maximum SDU Size",                   "btl2cap.option_sdu_size",
1599                                 FT_UINT16, BASE_DEC, NULL, 0x0,
1600                                 NULL, HFILL }
1601                 },
1602                 { &hf_btl2cap_option_sdu_arrival_time,
1603                         { "SDU Inter-arrival Time (us)",                   "btl2cap.option_sdu_arrival_time",
1604                                 FT_UINT32, BASE_DEC, NULL, 0x0,
1605                                 "SDU Inter-arrival Time (microseconds)", HFILL }
1606                 },
1607                 { &hf_btl2cap_option_identifier,
1608                         { "Identifier",                   "btl2cap.option_ident",
1609                                 FT_UINT8, BASE_HEX, NULL, 0x0,
1610                                 "Flow Specification Identifier", HFILL }
1611                 },
1612                 { &hf_btl2cap_option_access_latency,
1613                         { "Access Latency (us)",                   "btl2cap.option_access_latency",
1614                                 FT_UINT32, BASE_DEC, NULL, 0x0,
1615                                 "Access Latency (microseconds)", HFILL }
1616                 },
1617                 { &hf_btl2cap_option_flags,
1618                         { "Flags",           "btl2cap.option_flags",
1619                                 FT_UINT8, BASE_HEX, NULL, 0x0,
1620                                 "Flags - must be set to 0 (Reserved for future use)", HFILL }
1621                 },
1622                 { &hf_btl2cap_option_service_type,
1623                         { "Service Type",           "btl2cap.option_servicetype",
1624                                 FT_UINT8, BASE_HEX, VALS(option_servicetype_vals), 0x0,
1625                                 "Level of service required", HFILL }
1626                 },
1627                 { &hf_btl2cap_option_tokenrate,
1628                         { "Token Rate (bytes/s)",           "btl2cap.option_tokenrate",
1629                                 FT_UINT32, BASE_DEC, NULL, 0x0,
1630                                 "Rate at which traffic credits are granted (bytes/s)", HFILL }
1631                 },
1632                 { &hf_btl2cap_option_tokenbucketsize,
1633                         { "Token Bucket Size (bytes)",           "btl2cap.option_tokenbsize",
1634                                 FT_UINT32, BASE_DEC, NULL, 0x0,
1635                                 "Size of the token bucket (bytes)", HFILL }
1636                 },
1637                 { &hf_btl2cap_option_peakbandwidth,
1638                         { "Peak Bandwidth (bytes/s)",           "btl2cap.option_peakbandwidth",
1639                                 FT_UINT32, BASE_DEC, NULL, 0x0,
1640                                 "Limit how fast packets may be sent (bytes/s)", HFILL }
1641                 },
1642                 { &hf_btl2cap_option_latency,
1643                         { "Latency (microseconds)",           "btl2cap.option_latency",
1644                                 FT_UINT32, BASE_DEC, NULL, 0x0,
1645                                 "Maximal acceptable delay (microseconds)", HFILL }
1646                 },
1647                 { &hf_btl2cap_option_delayvariation,
1648                         { "Delay Variation (microseconds)",           "btl2cap.option_delayvar",
1649                                 FT_UINT32, BASE_DEC, NULL, 0x0,
1650                                 "Difference between maximum and minimum delay (microseconds)", HFILL }
1651                 },
1652                 { &hf_btl2cap_option_retransmissionmode,
1653                         { "Mode",                                                               "btl2cap.retransmissionmode",
1654                                 FT_UINT8, BASE_HEX, VALS(option_retransmissionmode_vals), 0x0,
1655                                 "Retransmission/Flow Control mode", HFILL }
1656                 },
1657                 { &hf_btl2cap_option_txwindow,
1658                         { "TxWindow",                                                   "btl2cap.txwindow",
1659                                 FT_UINT8, BASE_DEC, NULL, 0x0,
1660                                 "Retransmission window size", HFILL }
1661                 },
1662                 { &hf_btl2cap_option_maxtransmit,
1663                         { "MaxTransmit",                                                "btl2cap.maxtransmit",
1664                                 FT_UINT8, BASE_DEC, NULL, 0x0,
1665                                 "Maximum I-frame retransmissions", HFILL }
1666                 },
1667                 { &hf_btl2cap_option_retransmittimeout,
1668                         { "Retransmit timeout (ms)",                    "btl2cap.retransmittimeout",
1669                                 FT_UINT16, BASE_DEC, NULL, 0x0,
1670                                 "Retransmission timeout (milliseconds)", HFILL }
1671                 },
1672                 { &hf_btl2cap_option_monitortimeout,
1673                         { "Monitor Timeout (ms)",                               "btl2cap.monitortimeout",
1674                                 FT_UINT16, BASE_DEC, NULL, 0x0,
1675                                 "S-frame transmission interval (milliseconds)", HFILL }
1676                 },
1677                 { &hf_btl2cap_option_mps,
1678                         { "MPS",                                                                "btl2cap.mps",
1679                                 FT_UINT16, BASE_DEC, NULL, 0x0,
1680                                 "Maximum PDU Payload Size", HFILL }
1681                 },
1682                 { &hf_btl2cap_option_fcs,
1683                         { "FCS",                   "btl2cap.option_fcs",
1684                                 FT_UINT16, BASE_HEX, VALS(option_fcs_vals), 0x0,
1685                                 "Frame Check Sequence", HFILL }
1686                 },
1687                 { &hf_btl2cap_option_window,
1688                         { "Extended Window Size",                       "btl2cap.option_window",
1689                                 FT_UINT16, BASE_DEC, NULL, 0x0,
1690                                 NULL, HFILL }
1691                 },
1692                 { &hf_btl2cap_option,
1693                         { "Configuration Parameter Option",           "btl2cap.conf_param_option",
1694                                 FT_NONE, BASE_NONE, NULL, 0x0,
1695                                 NULL, HFILL }
1696                 },
1697                 { &hf_btl2cap_control_sar,
1698                         { "Segmentation and reassembly",           "btl2cap.control_sar",
1699                                 FT_UINT16, BASE_HEX, VALS(control_sar_vals), 0xC000,
1700                                 NULL, HFILL }
1701                 },
1702                 { &hf_btl2cap_control_reqseq,
1703                         { "ReqSeq",           "btl2cap.control_reqseq",
1704                                 FT_UINT16, BASE_DEC, NULL, 0x3F00,
1705                                 "Request Sequence Number", HFILL }
1706                 },
1707                 { &hf_btl2cap_control_txseq,
1708                         { "TxSeq",           "btl2cap.control_txseq",
1709                                 FT_UINT16, BASE_DEC, NULL, 0x007E,
1710                                 "Transmitted Sequence Number", HFILL }
1711                 },
1712                 { &hf_btl2cap_control_retransmissiondisable,
1713                         { "R",           "btl2cap.control_retransmissiondisable",
1714                                 FT_UINT16, BASE_HEX, NULL, 0x0080,
1715                                 "Retransmission Disable", HFILL }
1716                 },
1717                 { &hf_btl2cap_control_supervisory,
1718                         { "S",           "btl2cap.control_supervisory",
1719                                 FT_UINT16, BASE_HEX, VALS(control_supervisory_vals), 0x000C,
1720                                 "Supervisory Function", HFILL }
1721                 },
1722                 { &hf_btl2cap_control_type,
1723                         { "Frame Type",           "btl2cap.control_type",
1724                                 FT_UINT16, BASE_HEX, VALS(control_type_vals), 0x0001,
1725                                 NULL, HFILL }
1726                 },
1727                 { &hf_btl2cap_control,
1728                         { "Control field",           "btl2cap.control",
1729                                 FT_NONE, BASE_NONE, NULL, 0x0,
1730                                 NULL, HFILL }
1731                 },
1732                 { &hf_btl2cap_fcs,
1733                         { "FCS",           "btl2cap.fcs",
1734                                 FT_UINT16, BASE_HEX, NULL, 0,
1735                                 "Frame Check Sequence", HFILL }
1736                 },
1737                 { &hf_btl2cap_sdulength,
1738                         { "SDU Length",           "btl2cap.sdulength",
1739                                 FT_UINT16, BASE_DEC, NULL, 0,
1740                                 NULL, HFILL }
1741                 },
1742                 { &hf_btl2cap_reassembled_in,
1743                         { "This SDU is reassembled in frame",           "btl2cap.reassembled_in",
1744                                 FT_FRAMENUM, BASE_NONE, NULL, 0,
1745                                 "This SDU is reassembled in frame #", HFILL }
1746                 },
1747                 { &hf_btl2cap_continuation_to,
1748                         { "This is a continuation to the SDU in frame",           "btl2cap.continuation_to",
1749                                 FT_FRAMENUM, BASE_NONE, NULL, 0,
1750                                 "This is a continuation to the SDU in frame #", HFILL }
1751                 }
1752         };
1753
1754         /* Setup protocol subtree array */
1755         static gint *ett[] = {
1756                 &ett_btl2cap,
1757                 &ett_btl2cap_cmd,
1758                 &ett_btl2cap_option,
1759                 &ett_btl2cap_extfeatures,
1760                 &ett_btl2cap_fixedchans,
1761                 &ett_btl2cap_control
1762         };
1763
1764         /* Register the protocol name and description */
1765         proto_btl2cap = proto_register_protocol("Bluetooth L2CAP Protocol", "L2CAP", "btl2cap");
1766
1767         register_dissector("btl2cap", dissect_btl2cap, proto_btl2cap);
1768
1769         /* subdissector code */
1770         l2cap_psm_dissector_table = register_dissector_table("btl2cap.psm", "L2CAP PSM", FT_UINT16, BASE_HEX);
1771         l2cap_service_dissector_table = register_dissector_table("btl2cap.service", "L2CAP Service", FT_UINT16, BASE_HEX);
1772         l2cap_cid_dissector_table = register_dissector_table("btl2cap.cid", "L2CAP CID", FT_UINT16, BASE_HEX);
1773
1774         /* Required function calls to register the header fields and subtrees used */
1775         proto_register_field_array(proto_btl2cap, hf, array_length(hf));
1776         proto_register_subtree_array(ett, array_length(ett));
1777
1778         cid_to_psm_table=se_tree_create(EMEM_TREE_TYPE_RED_BLACK, "btl2cap scid to psm");
1779         psm_to_service_table=se_tree_create(EMEM_TREE_TYPE_RED_BLACK, "btl2cap psm to service uuid");
1780 }
1781
1782
1783 void 
1784 proto_reg_handoff_btl2cap(void)
1785 {
1786         /* tap into the btsdp dissector to look for l2cap PSM infomation that
1787            helps us determine the type of l2cap payload, i.e. which service is
1788            using the PSM channel so we know which sub-dissector to call */
1789         register_tap_listener("btsdp", NULL, NULL, 0, NULL, btl2cap_sdp_tap_packet, NULL);
1790 }
1791
1792