Coverage Report

Created: 2025-12-27 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-btl2cap.c
Line
Count
Source
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
 * Added handling and reassembly of LE-Frames
10
 *   Anders Broman at ericsson dot com 2016
11
 *
12
 * Wireshark - Network traffic analyzer
13
 * By Gerald Combs <gerald@wireshark.org>
14
 * Copyright 1998 Gerald Combs
15
 *
16
 * SPDX-License-Identifier: GPL-2.0-or-later
17
 */
18
19
#include "config.h"
20
21
#include <epan/packet.h>
22
#include <epan/crc16-tvb.h>
23
#include <epan/exceptions.h>
24
#include <epan/expert.h>
25
#include <epan/decode_as.h>
26
#include <epan/proto_data.h>
27
#include <epan/reassemble.h>
28
#include <epan/unit_strings.h>
29
30
#include <wiretap/wtap.h>
31
32
#include "packet-bluetooth.h"
33
#include "packet-bthci_acl.h"
34
#include "packet-btsdp.h"
35
#include "packet-btl2cap.h"
36
37
/* Initialize the protocol and registered fields */
38
int proto_btl2cap;
39
40
static int hf_btl2cap_length;
41
static int hf_btl2cap_cid;
42
static int hf_btl2cap_payload;
43
static int hf_btl2cap_command;
44
static int hf_btl2cap_cmd_code;
45
static int hf_btl2cap_cmd_ident;
46
static int hf_btl2cap_cmd_length;
47
static int hf_btl2cap_cmd_data;
48
static int hf_btl2cap_psm;
49
static int hf_btl2cap_psm_dynamic;
50
static int hf_btl2cap_scid;
51
static int hf_btl2cap_dcid;
52
static int hf_btl2cap_icid;
53
static int hf_btl2cap_controller;
54
static int hf_btl2cap_dcontroller;
55
static int hf_btl2cap_result;
56
static int hf_btl2cap_move_result;
57
static int hf_btl2cap_move_confirmation_result;
58
static int hf_btl2cap_status;
59
static int hf_btl2cap_rej_reason;
60
static int hf_btl2cap_sig_mtu;
61
static int hf_btl2cap_info_mtu;
62
static int hf_btl2cap_info_flowcontrol;
63
static int hf_btl2cap_info_retransmission;
64
static int hf_btl2cap_info_bidirqos;
65
static int hf_btl2cap_info_enh_retransmission;
66
static int hf_btl2cap_info_streaming;
67
static int hf_btl2cap_info_fcs;
68
static int hf_btl2cap_info_flow_spec;
69
static int hf_btl2cap_info_fixedchan;
70
static int hf_btl2cap_info_fixedchans;
71
static int hf_btl2cap_info_fixedchans_null;
72
static int hf_btl2cap_info_fixedchans_signal;
73
static int hf_btl2cap_info_fixedchans_connless;
74
static int hf_btl2cap_info_fixedchans_amp_man;
75
static int hf_btl2cap_info_fixedchans_rfu;
76
static int hf_btl2cap_info_fixedchans_smp;
77
static int hf_btl2cap_info_fixedchans_amp_test;
78
static int hf_btl2cap_info_window;
79
static int hf_btl2cap_info_unicast;
80
static int hf_btl2cap_info_type;
81
static int hf_btl2cap_info_result;
82
static int hf_btl2cap_configuration_result;
83
static int hf_btl2cap_info_extfeatures;
84
static int hf_btl2cap_option;
85
static int hf_btl2cap_option_type;
86
static int hf_btl2cap_option_length;
87
static int hf_btl2cap_option_mtu;
88
static int hf_btl2cap_option_flushTO;
89
static int hf_btl2cap_option_flush_to_us;
90
static int hf_btl2cap_option_flags;
91
static int hf_btl2cap_option_service_type;
92
static int hf_btl2cap_option_tokenrate;
93
static int hf_btl2cap_option_tokenbucketsize;
94
static int hf_btl2cap_option_peakbandwidth;
95
static int hf_btl2cap_option_latency;
96
static int hf_btl2cap_option_delayvariation;
97
static int hf_btl2cap_option_retransmissionmode;
98
static int hf_btl2cap_option_txwindow;
99
static int hf_btl2cap_option_maxtransmit;
100
static int hf_btl2cap_option_retransmittimeout;
101
static int hf_btl2cap_option_monitortimeout;
102
static int hf_btl2cap_option_mps;
103
static int hf_btl2cap_option_fcs;
104
static int hf_btl2cap_option_window;
105
static int hf_btl2cap_option_identifier;
106
static int hf_btl2cap_option_sdu_size;
107
static int hf_btl2cap_option_sdu_arrival_time;
108
static int hf_btl2cap_option_access_latency;
109
static int hf_btl2cap_control_field;
110
static int hf_btl2cap_ext_control_field;
111
static int hf_btl2cap_control_sar;
112
static int hf_btl2cap_ext_control_sar;
113
static int hf_btl2cap_control_reqseq;
114
static int hf_btl2cap_ext_control_reqseq;
115
static int hf_btl2cap_control_txseq;
116
static int hf_btl2cap_ext_control_txseq;
117
static int hf_btl2cap_control_retransmissiondisable;
118
static int hf_btl2cap_control_poll;
119
static int hf_btl2cap_ext_control_poll;
120
static int hf_btl2cap_control_final;
121
static int hf_btl2cap_ext_control_final;
122
static int hf_btl2cap_control_supervisory;
123
static int hf_btl2cap_ext_control_supervisory;
124
static int hf_btl2cap_control_type;
125
static int hf_btl2cap_ext_control_type;
126
static int hf_btl2cap_fcs;
127
static int hf_btl2cap_fcs_status;
128
static int hf_btl2cap_sdulength;
129
static int hf_btl2cap_continuation_to;
130
static int hf_btl2cap_reassembled_in;
131
static int hf_btl2cap_min_interval;
132
static int hf_btl2cap_max_interval;
133
static int hf_btl2cap_peripheral_latency;
134
static int hf_btl2cap_timeout_multiplier;
135
static int hf_btl2cap_conn_param_result;
136
static int hf_btl2cap_credits;
137
static int hf_btl2cap_initial_credits;
138
static int hf_btl2cap_le_result;
139
static int hf_btl2cap_le_psm;
140
static int hf_btl2cap_flags_reserved;
141
static int hf_btl2cap_flags_continuation;
142
static int hf_btl2cap_data;
143
static int hf_btl2cap_service;
144
static int hf_btl2cap_connect_in_frame;
145
static int hf_btl2cap_disconnect_in_frame;
146
147
static int hf_btl2cap_le_sdu_fragments;
148
static int hf_btl2cap_le_sdu_fragment;
149
static int hf_btl2cap_le_sdu_fragment_overlap;
150
static int hf_btl2cap_le_sdu_fragment_overlap_conflicts;
151
static int hf_btl2cap_le_sdu_fragment_multiple_tails;
152
static int hf_btl2cap_le_sdu_fragment_too_long_fragment;
153
static int hf_btl2cap_le_sdu_fragment_error;
154
static int hf_btl2cap_le_sdu_fragment_count;
155
static int hf_btl2cap_le_sdu_reassembled_in;
156
static int hf_btl2cap_le_sdu_reassembled_length;
157
158
static int hf_btl2cap_le_sdu_length;
159
160
/* Initialize the subtree pointers */
161
static int ett_btl2cap;
162
static int ett_btl2cap_cmd;
163
static int ett_btl2cap_option;
164
static int ett_btl2cap_extfeatures;
165
static int ett_btl2cap_fixedchans;
166
static int ett_btl2cap_control;
167
static int ett_btl2cap_le_sdu_fragment;
168
static int ett_btl2cap_le_sdu_fragments;
169
170
static expert_field ei_btl2cap_parameter_mismatch;
171
static expert_field ei_btl2cap_sdulength_bad;
172
static expert_field ei_btl2cap_length_bad;
173
static expert_field ei_btl2cap_fcs_bad;
174
static expert_field ei_btl2cap_unknown_command_code;
175
176
/* Initialize dissector table */
177
static dissector_table_t l2cap_psm_dissector_table;
178
static dissector_table_t l2cap_cid_dissector_table;
179
180
/* This table maps command identity values to psm values. */
181
static wmem_tree_t *cmd_ident_to_psm_table;
182
183
/* This table maps cid values to psm values.
184
 * The same table is used both for SCID and DCID.
185
 * For Remote CIDs (Receive Request SCID or Sent Response DCID)
186
 * we 'or' the CID with 0x80000000 in this table
187
 */
188
static wmem_tree_t *cid_to_psm_table;
189
190
/* 5.4 RETRANSMISSION AND FLOW CONTROL OPTION
191
 * Table 5.2
192
 * Mode
193
 * 0x00 L2CAP Basic Mode
194
 * 0x01 Retransmission mode
195
 * 0x02 Flow control mode
196
 * 0x03 Enhanced Retransmission mode
197
 * 0x04 Streaming mode
198
 * Other values Reserved for future use
199
 */
200
0
#define L2CAP_BASIC_MODE                      0
201
#define L2CAP_RETRANSMISSION_MODE             1
202
#define L2CAP_FLOW_CONTROL_MODE               2
203
0
#define L2CAP_ENHANCED_RETRANSMISSION_MODE    3
204
0
#define L2CAP_STREAMING_MODE                  4
205
206
/* XXX Cheat and define a vaue for
207
 * Connection-Oriented Channels in LE Credit Based Flow Control Mode
208
 */
209
6.78k
#define L2CAP_LE_CREDIT_BASED_FLOW_CONTROL_MODE 0xff
210
211
enum l2cap_ctl_field_format {
212
    L2CAP_IFRAME_CONTROL_FIELD_STANDARD,
213
    L2CAP_IFRAME_CONTROL_FIELD_ENHANCED,
214
    L2CAP_IFRAME_CONTROL_FIELD_EXTENDED,
215
};
216
217
typedef struct _config_data_t {
218
    uint8_t     mode;
219
    uint8_t     txwindow;
220
    /* Extended Window Size option */
221
    uint16_t    maxwindowsize;
222
    wmem_tree_t *start_fragments;  /* indexed by pinfo->num */
223
    /* Used for LE frame reassembly */
224
    unsigned segmentation_started : 1;  /* 0 = No, 1 = Yes */
225
    unsigned segment_len_rem;          /* The remaining segment length, used to find last segment */
226
} config_data_t;
227
228
typedef struct _sdu_reassembly_t
229
{
230
    uint8_t *reassembled;
231
    uint8_t  seq;
232
    uint32_t first_frame;
233
    uint32_t last_frame;
234
    uint16_t tot_len;
235
    int      cur_off;           /* counter used by reassembly */
236
} sdu_reassembly_t;
237
238
typedef struct _psm_data_t {
239
    uint32_t      interface_id;
240
    uint32_t      adapter_id;
241
    uint32_t      chandle;
242
    uint32_t      local_cid;
243
    uint32_t      remote_cid;
244
    uint16_t      psm;
245
    bool          local_service;
246
    uint32_t      connect_in_frame;
247
    uint32_t      disconnect_in_frame;
248
    config_data_t in;
249
    config_data_t out;
250
} psm_data_t;
251
252
typedef struct _btl2cap_frame_data_t
253
{
254
    /* LE frames info */
255
    unsigned first_fragment : 1; /* 0 = No, 1 = First or only fragment*/
256
    unsigned more_fragments : 1; /* 0 = Last fragment, 1 = more fragments*/
257
} btl2cap_frame_data_t;
258
259
static const value_string command_code_vals[] = {
260
    { 0x01,   "Command Reject" },
261
    { 0x02,   "Connection Request" },
262
    { 0x03,   "Connection Response" },
263
    { 0x04,   "Configure Request" },
264
    { 0x05,   "Configure Response" },
265
    { 0x06,   "Disconnection Request" },
266
    { 0x07,   "Disconnection Response" },
267
    { 0x08,   "Echo Request" },
268
    { 0x09,   "Echo Response" },
269
    { 0x0A,   "Information Request" },
270
    { 0x0B,   "Information Response" },
271
    { 0x0C,   "Create Channel Request" },
272
    { 0x0D,   "Create Channel Response" },
273
    { 0x0E,   "Move Channel Request" },
274
    { 0x0F,   "Move Channel Response" },
275
    { 0x10,   "Move Channel Confirmation" },
276
    { 0x11,   "Move Channel Confirmation Response" },
277
    { 0x12,   "Connection Parameter Update Request" },
278
    { 0x13,   "Connection Parameter Update Response" },
279
    { 0x14,   "LE Credit Based Connection Request" },
280
    { 0x15,   "LE Credit Based Connection Response" },
281
    { 0x16,   "LE Flow Control Credit" },
282
    { 0x17,   "L2CAP Credit Based Connection Request" },
283
    { 0x18,   "L2CAP Credit Based Connection Response" },
284
    { 0x19,   "L2CAP Credit Based Reconfigure Request" },
285
    { 0x1A,   "L2CAP Credit Based Reconfigure Response" },
286
    { 0, NULL }
287
};
288
289
290
static const value_string psm_vals[] = {
291
    { 0x0001, "SDP" },
292
    { 0x0003, "RFCOMM" },
293
    { 0x0005, "TCS-BIN" },
294
    { 0x0007, "TCS-BIN-CORDLESS" },
295
    { 0x000F, "BNEP" },
296
    { 0x0011, "HID-Control" },
297
    { 0x0013, "HID-Interrupt" },
298
    { 0x0015, "UPnP" },
299
    { 0x0017, "AVCTP-Control" },
300
    { 0x0019, "AVDTP" },
301
    { 0x001B, "AVCTP-Browsing" },
302
    { 0x001D, "UDI_C-Plane" },
303
    { 0x001F, "ATT" },
304
    { 0x0021, "3DSP" },
305
    { 0x0023, "IPSP" },
306
    { 0x0025, "OTS" },
307
    { 0x0027, "EATT" },
308
    { 0, NULL }
309
};
310
value_string_ext ext_psm_vals = VALUE_STRING_EXT_INIT(psm_vals);
311
312
static const value_string result_vals[] = {
313
    { 0x0000, "Successful" },
314
    { 0x0001, "Pending" },
315
    { 0x0002, "Refused - PSM not supported" },
316
    { 0x0003, "Refused - security block" },
317
    { 0x0004, "Refused - no resources available" },
318
    { 0x0005, "Refused - Controller ID not supported" },
319
    { 0, NULL }
320
};
321
322
static const value_string le_result_vals[] = {
323
    { 0x0000, "Connection Successful" },
324
    { 0x0002, "Connection Refused - LE_PSM Not Supported" },
325
    { 0x0004, "Connection Refused - No Resources Available" },
326
    { 0x0005, "Connection Refused - Insufficient Authentication" },
327
    { 0x0006, "Connection Refused - Insufficient Authorization" },
328
    { 0x0007, "Connection Refused - Insufficient Encryption Key Size" },
329
    { 0x0008, "Connection Refused - Insufficient Encryption" },
330
    { 0, NULL }
331
};
332
333
static const value_string move_result_vals[] = {
334
    { 0x0000, "Success" },
335
    { 0x0001, "Pending" },
336
    { 0x0002, "Refused - Controller ID not supported" },
337
    { 0x0003, "Refused - New Controller ID is same as old" },
338
    { 0x0004, "Refused - Configuration not supported" },
339
    { 0x0005, "Refused - Move Channel collision" },
340
    { 0x0006, "Refused - Channel not allowed to be moved" },
341
    { 0, NULL }
342
};
343
344
static const value_string move_result_confirmation_vals[] = {
345
    { 0x0000,   "Success - both sides succeed" },
346
    { 0x0001,   "Failure - one or both sides refuse" },
347
    { 0, NULL }
348
};
349
350
static const value_string configuration_result_vals[] = {
351
    { 0x0000, "Success"},
352
    { 0x0001, "Failure - unacceptable parameters" },
353
    { 0x0002, "Failure - reject (no reason provided)" },
354
    { 0x0003, "Failure - unknown options" },
355
    { 0x0004, "Pending" },
356
    { 0x0005, "Failure - flow spec rejected" },
357
    { 0, NULL }
358
};
359
360
static const value_string conn_param_result_vals[] = {
361
    { 0x0000,   "Accepted" },
362
    { 0x0001,   "Rejected" },
363
    { 0, NULL }
364
};
365
366
static const value_string status_vals[] = {
367
    { 0x0000, "No further information available" },
368
    { 0x0001, "Authentication pending" },
369
    { 0x0002, "Authorization pending" },
370
    { 0, NULL }
371
};
372
373
static const value_string reason_vals[] = {
374
    { 0x0000, "Command not understood" },
375
    { 0x0001, "Signaling MTU exceeded" },
376
    { 0x0002, "Invalid CID in request" },
377
    { 0, NULL }
378
};
379
380
static const value_string info_type_vals[] = {
381
    { 0x0001, "Connectionless MTU" },
382
    { 0x0002, "Extended Features Mask" },
383
    { 0x0003, "Fixed Channels Supported" },
384
    { 0, NULL }
385
};
386
387
static const value_string info_result_vals[] = {
388
    { 0x0000, "Success" },
389
    { 0x0001, "Not Supported" },
390
    { 0, NULL }
391
};
392
393
static const value_string option_servicetype_vals[] = {
394
    { 0x00,   "No traffic" },
395
    { 0x01,   "Best effort (Default)" },
396
    { 0x02,   "Guaranteed" },
397
    { 0, NULL }
398
};
399
400
static const value_string option_type_vals[] = {
401
    { 0x01,   "Maximum Transmission Unit" },
402
    { 0x02,   "Flush Timeout" },
403
    { 0x03,   "Quality of Service" },
404
    { 0x04,   "Retransmission and Flow Control" },
405
    { 0x05,   "FCS" },
406
    { 0x06,   "Extended Flow Specification" },
407
    { 0x07,   "Extended Window Size" },
408
    { 0, NULL }
409
};
410
411
static const value_string option_retransmissionmode_vals[] = {
412
    { 0x00,   "Basic Mode" },
413
    { 0x01,   "Retransmission Mode" },
414
    { 0x02,   "Flow Control Mode" },
415
    { 0x03,   "Enhanced Retransmission Mode" },
416
    { 0x04,   "Streaming Mode" },
417
    { 0, NULL }
418
};
419
420
static const value_string control_sar_vals[] = {
421
    { 0x00,   "Unsegmented" },
422
    { 0x01,   "Start" },
423
    { 0x02,   "End" },
424
    { 0x03,   "Continuation" },
425
    { 0, NULL }
426
};
427
428
static const value_string control_supervisory_vals[] = {
429
    { 0x00,   "RR" },
430
    { 0x01,   "REJ" },
431
    { 0x02,   "RNR" },
432
    { 0x03,   "SREJ" },
433
    { 0, NULL }
434
};
435
436
static const value_string control_type_vals[] = {
437
    { 0x00,   "I-Frame" },
438
    { 0x01,   "S-Frame" },
439
    { 0, NULL }
440
};
441
442
static const value_string option_fcs_vals[] = {
443
    { 0x00,   "No FCS" },
444
    { 0x01,   "16-bit FCS" },
445
    { 0, NULL }
446
};
447
448
static const value_string ctrl_id_code_vals[] = {
449
    { 0x00,   "Bluetooth BR/EDR" },
450
    { 0x01,   "Wifi 802.11" },
451
    { 0, NULL }
452
};
453
454
static const range_string cid_rvals[] = {
455
    { 0x0000, 0x0000,  "Null identifier" },
456
    { 0x0001, 0x0001,  "L2CAP Signaling Channel" },
457
    { 0x0002, 0x0002,  "Connectionless Channel" },
458
    { 0x0003, 0x0003,  "AMP Manager Protocol" },
459
    { 0x0004, 0x0004,  "Attribute Protocol" },
460
    { 0x0005, 0x0005,  "L2CAP LE Signaling Channel" },
461
    { 0x0006, 0x0006,  "Security Manager Protocol" },
462
    { 0x0007, 0x0007,  "BR/EDR Security Manager Protocol" },
463
    { 0x0008, 0x003E,  "Reserved" },
464
    { 0x003F, 0x003F,  "AMP Test Manager" },
465
    { 0x0040, 0xFFFF,  "Dynamically Allocated" },
466
    { 0, 0, NULL }
467
};
468
469
static const range_string le_psm_rvals[] = {
470
    { 0x0001, 0x007F,  "Fixed, SIG Assigned" },
471
    { 0x0080, 0x00FF,  "Dynamically Allocated" },
472
    { 0x0100, 0xFFFF,  "Reserved" },
473
    { 0, 0, NULL }
474
};
475
476
static const unit_name_string units_ll_connection_event = { " LL Connection Event", " LL Connection Events" };
477
478
4.08k
#define PROTO_DATA_BTL2CAP_CID        0
479
902
#define PROTO_DATA_BTL2CAP_PSM        1
480
481
void proto_register_btl2cap(void);
482
void proto_reg_handoff_btl2cap(void);
483
484
/* Reassembly */
485
static reassembly_table btl2cap_le_sdu_reassembly_table;
486
487
static const fragment_items btl2cap_le_sdu_frag_items = {
488
    /* Fragment subtrees */
489
    &ett_btl2cap_le_sdu_fragment,
490
    &ett_btl2cap_le_sdu_fragments,
491
    /* Fragment fields */
492
    &hf_btl2cap_le_sdu_fragments,
493
    &hf_btl2cap_le_sdu_fragment,
494
    &hf_btl2cap_le_sdu_fragment_overlap,
495
    &hf_btl2cap_le_sdu_fragment_overlap_conflicts,
496
    &hf_btl2cap_le_sdu_fragment_multiple_tails,
497
    &hf_btl2cap_le_sdu_fragment_too_long_fragment,
498
    &hf_btl2cap_le_sdu_fragment_error,
499
    &hf_btl2cap_le_sdu_fragment_count,
500
    /* Reassembled in field */
501
    &hf_btl2cap_le_sdu_reassembled_in,
502
    /* Reassembled length field */
503
    &hf_btl2cap_le_sdu_reassembled_length,
504
    /* Reassembled data field */
505
    NULL,
506
    /* Tag */
507
    "BTL2CAP LE SDU fragments"
508
};
509
510
511
static void btl2cap_cid_prompt(packet_info *pinfo, char* result)
512
0
{
513
0
    uint16_t *value_data;
514
515
0
    value_data = (uint16_t *) p_get_proto_data(pinfo->pool, pinfo, proto_btl2cap, PROTO_DATA_BTL2CAP_CID);
516
0
    if (value_data)
517
0
        snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "L2CAP CID 0x%04x as", (unsigned) *value_data);
518
0
    else
519
0
        snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "Unknown L2CAP CID");
520
0
}
521
522
static void *btl2cap_cid_value(packet_info *pinfo)
523
0
{
524
0
    uint16_t *value_data;
525
526
0
    value_data = (uint16_t *) p_get_proto_data(pinfo->pool, pinfo, proto_btl2cap, PROTO_DATA_BTL2CAP_CID);
527
528
0
    if (value_data)
529
0
        return GUINT_TO_POINTER((unsigned long)*value_data);
530
531
0
    return NULL;
532
0
}
533
534
static void btl2cap_psm_prompt(packet_info *pinfo, char* result)
535
0
{
536
0
    uint16_t *value_data;
537
538
0
    value_data = (uint16_t *) p_get_proto_data(pinfo->pool, pinfo, proto_btl2cap, PROTO_DATA_BTL2CAP_PSM);
539
0
    if (value_data)
540
0
        snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "L2CAP PSM 0x%04x as", (unsigned) *value_data);
541
0
    else
542
0
        snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "Unknown L2CAP PSM");
543
0
}
544
545
static void *btl2cap_psm_value(packet_info *pinfo)
546
0
{
547
0
    uint16_t *value_data;
548
549
0
    value_data = (uint16_t *) p_get_proto_data(pinfo->pool, pinfo, proto_btl2cap, PROTO_DATA_BTL2CAP_PSM);
550
551
0
    if (value_data)
552
0
        return GUINT_TO_POINTER((unsigned long)*value_data);
553
554
0
    return NULL;
555
0
}
556
557
static uint16_t
558
get_service_uuid(packet_info *pinfo, btl2cap_data_t *l2cap_data, uint16_t psm, bool is_local_psm)
559
3.53k
{
560
3.53k
    wmem_tree_key_t    key[10];
561
3.53k
    uint32_t           k_interface_id;
562
3.53k
    uint32_t           k_adapter_id;
563
3.53k
    uint32_t           k_sdp_psm;
564
3.53k
    uint32_t           k_direction;
565
3.53k
    uint32_t           k_bd_addr_oui;
566
3.53k
    uint32_t           k_bd_addr_id;
567
3.53k
    uint32_t           k_service_type;
568
3.53k
    uint32_t           k_service_channel;
569
3.53k
    uint32_t           k_frame_number;
570
3.53k
    uint32_t           interface_id;
571
3.53k
    uint32_t           adapter_id;
572
3.53k
    uint32_t           remote_bd_addr_oui;
573
3.53k
    uint32_t           remote_bd_addr_id;
574
3.53k
    service_info_t    *service_info;
575
576
3.53k
    interface_id       = l2cap_data->interface_id;
577
3.53k
    adapter_id         = l2cap_data->adapter_id;
578
579
3.53k
    k_interface_id    = interface_id;
580
3.53k
    k_adapter_id      = adapter_id;
581
3.53k
    k_sdp_psm         = SDP_PSM_DEFAULT;
582
3.53k
    k_direction       = (is_local_psm) ? P2P_DIR_SENT : P2P_DIR_RECV;
583
3.53k
    if (k_direction == P2P_DIR_RECV) {
584
3.53k
        k_bd_addr_oui = l2cap_data->remote_bd_addr_oui;
585
3.53k
        k_bd_addr_id  = l2cap_data->remote_bd_addr_id;
586
3.53k
    } else {
587
0
        k_bd_addr_oui = 0;
588
0
        k_bd_addr_id  = 0;
589
0
    }
590
591
3.53k
    remote_bd_addr_oui = k_bd_addr_oui;
592
3.53k
    remote_bd_addr_id  = k_bd_addr_id;
593
594
3.53k
    k_service_type    = BTSDP_L2CAP_PROTOCOL_UUID;
595
3.53k
    k_service_channel = psm;
596
3.53k
    k_frame_number    = pinfo->num;
597
598
3.53k
    key[0].length = 1;
599
3.53k
    key[0].key = &k_interface_id;
600
3.53k
    key[1].length = 1;
601
3.53k
    key[1].key = &k_adapter_id;
602
3.53k
    key[2].length = 1;
603
3.53k
    key[2].key = &k_sdp_psm;
604
3.53k
    key[3].length = 1;
605
3.53k
    key[3].key = &k_direction;
606
3.53k
    key[4].length = 1;
607
3.53k
    key[4].key = &k_bd_addr_oui;
608
3.53k
    key[5].length = 1;
609
3.53k
    key[5].key = &k_bd_addr_id;
610
3.53k
    key[6].length = 1;
611
3.53k
    key[6].key = &k_service_type;
612
3.53k
    key[7].length = 1;
613
3.53k
    key[7].key = &k_service_channel;
614
3.53k
    key[8].length = 1;
615
3.53k
    key[8].key = &k_frame_number;
616
3.53k
    key[9].length = 0;
617
3.53k
    key[9].key = NULL;
618
619
3.53k
    service_info = btsdp_get_service_info(key);
620
621
3.53k
    if (service_info &&
622
0
        service_info->interface_id == interface_id &&
623
0
        service_info->adapter_id == adapter_id &&
624
0
        service_info->sdp_psm == SDP_PSM_DEFAULT &&
625
0
        ((service_info->direction == P2P_DIR_RECV &&
626
0
          service_info->bd_addr_oui == remote_bd_addr_oui &&
627
0
          service_info->bd_addr_id == remote_bd_addr_id) ||
628
0
         (service_info->direction != P2P_DIR_RECV &&
629
0
          service_info->bd_addr_oui == 0 &&
630
0
          service_info->bd_addr_id == 0)) &&
631
0
        service_info->type == BTSDP_L2CAP_PROTOCOL_UUID &&
632
0
        service_info->channel == psm)
633
0
    {
634
0
        return service_info->uuid.bt_uuid;
635
0
    }
636
637
3.53k
    return 0;
638
3.53k
}
639
640
static int
641
dissect_comrej(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
642
175
{
643
175
    uint16_t reason;
644
645
175
    reason  = tvb_get_letohs(tvb, offset);
646
175
    proto_tree_add_item(tree, hf_btl2cap_rej_reason, tvb, offset, 2, ENC_LITTLE_ENDIAN);
647
175
    offset += 2;
648
649
175
    switch (reason) {
650
4
    case 0x0000: /* Command not understood */
651
4
        break;
652
653
8
    case 0x0001: /* Signaling MTU exceeded */
654
8
        proto_tree_add_item(tree, hf_btl2cap_sig_mtu, tvb, offset, 2, ENC_LITTLE_ENDIAN);
655
8
        offset += 2;
656
8
        break;
657
658
2
    case 0x0002: /* Invalid CID in requests */
659
2
        proto_tree_add_item(tree, hf_btl2cap_scid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
660
2
        offset += 2;
661
662
2
        proto_tree_add_item(tree, hf_btl2cap_dcid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
663
2
        offset += 2;
664
665
2
        break;
666
667
161
    default:
668
161
        break;
669
175
    }
670
671
175
    return offset;
672
175
}
673
674
static int
675
dissect_connrequest(tvbuff_t *tvb, int offset, packet_info *pinfo,
676
        proto_tree *tree, proto_tree *command_tree, bool is_ch_request,
677
        bthci_acl_data_t *acl_data, btl2cap_data_t *l2cap_data)
678
116
{
679
116
    uint16_t           scid;
680
116
    uint16_t           psm;
681
116
    const char        *psm_str = "<NONE>";
682
683
116
    psm = tvb_get_letohs(tvb, offset);
684
685
116
    if (p_get_proto_data(pinfo->pool, pinfo, proto_btl2cap, PROTO_DATA_BTL2CAP_PSM ) == NULL) {
686
92
        uint16_t *value_data;
687
688
92
        value_data = wmem_new(wmem_file_scope(), uint16_t);
689
92
        *value_data = psm;
690
691
92
        p_add_proto_data(pinfo->pool, pinfo, proto_btl2cap, PROTO_DATA_BTL2CAP_PSM, value_data);
692
92
    }
693
694
116
    if (psm < BTL2CAP_DYNAMIC_PSM_START) {
695
88
        proto_tree_add_item(command_tree, hf_btl2cap_psm, tvb, offset, 2, ENC_LITTLE_ENDIAN);
696
88
        psm_str = val_to_str_const(psm, psm_vals, "Unknown PSM");
697
88
    } else {
698
28
        proto_item  *item;
699
28
        uint16_t     uuid;
700
701
28
        item = proto_tree_add_item(command_tree, hf_btl2cap_psm_dynamic, tvb, offset, 2, ENC_LITTLE_ENDIAN);
702
703
28
        uuid = get_service_uuid(pinfo, l2cap_data, psm, (pinfo->p2p_dir == P2P_DIR_RECV) ? true : false);
704
28
        if (uuid) {
705
0
            psm_str = val_to_str_ext_const(uuid, &bluetooth_uuid_vals_ext, "Unknown PSM");
706
0
            proto_item_append_text(item, " (%s)", psm_str);
707
0
        }
708
28
    }
709
116
    offset += 2;
710
711
116
    scid = tvb_get_letohs(tvb, offset);
712
116
    proto_tree_add_item(command_tree, hf_btl2cap_scid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
713
116
    offset += 2;
714
715
116
    col_append_fstr(pinfo->cinfo, COL_INFO, " (%s, SCID: 0x%04x)", psm_str, scid);
716
717
116
    if (is_ch_request) {
718
3
        proto_tree_add_item(command_tree, hf_btl2cap_controller, tvb, offset, 1, ENC_LITTLE_ENDIAN);
719
3
        offset += 1;
720
3
    }
721
722
116
    if (!pinfo->fd->visited) {
723
116
        wmem_tree_key_t    key[6];
724
116
        uint32_t           k_interface_id;
725
116
        uint32_t           k_adapter_id;
726
116
        uint32_t           k_chandle;
727
116
        uint32_t           k_cid;
728
116
        uint32_t           k_frame_number;
729
116
        uint32_t           interface_id;
730
116
        uint32_t           adapter_id;
731
116
        uint32_t           chandle;
732
116
        psm_data_t        *psm_data;
733
734
116
        if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID)
735
0
            interface_id = pinfo->rec->rec_header.packet_header.interface_id;
736
116
        else
737
116
            interface_id = HCI_INTERFACE_DEFAULT;
738
116
        adapter_id   = (acl_data) ? acl_data->adapter_id : HCI_ADAPTER_DEFAULT;
739
116
        chandle      = (acl_data) ? acl_data->chandle : 0;
740
741
116
        k_interface_id = interface_id;
742
116
        k_adapter_id   = adapter_id;
743
116
        k_chandle      = chandle;
744
116
        k_cid          = scid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x80000000 : 0x00000000);
745
116
        k_frame_number = pinfo->num;
746
747
116
        psm_data = wmem_new0(wmem_file_scope(), psm_data_t);
748
116
        if (pinfo->p2p_dir == P2P_DIR_RECV) {
749
0
            psm_data->local_cid = BTL2CAP_UNKNOWN_CID;
750
0
            psm_data->remote_cid = scid |  0x80000000;
751
116
        } else {
752
116
            psm_data->local_cid = scid;
753
116
            psm_data->remote_cid = BTL2CAP_UNKNOWN_CID;
754
116
        }
755
116
        psm_data->psm  = psm;
756
116
        psm_data->local_service = (pinfo->p2p_dir == P2P_DIR_RECV) ? true : false;
757
116
        psm_data->in.start_fragments = wmem_tree_new(wmem_file_scope());
758
116
        psm_data->out.start_fragments = wmem_tree_new(wmem_file_scope());
759
116
        psm_data->interface_id = k_interface_id;
760
116
        psm_data->adapter_id   = k_adapter_id;
761
116
        psm_data->chandle      = k_chandle;
762
116
        psm_data->connect_in_frame = pinfo->num;
763
116
        psm_data->disconnect_in_frame = bluetooth_max_disconnect_in_frame;
764
765
116
        key[0].length = 1;
766
116
        key[0].key    = &k_interface_id;
767
116
        key[1].length = 1;
768
116
        key[1].key    = &k_adapter_id;
769
116
        key[2].length = 1;
770
116
        key[2].key    = &k_chandle;
771
116
        key[3].length = 1;
772
116
        key[3].key    = &k_cid;
773
116
        key[4].length = 1;
774
116
        key[4].key    = &k_frame_number;
775
116
        key[5].length = 0;
776
116
        key[5].key    = NULL;
777
778
116
        wmem_tree_insert32_array(cid_to_psm_table, key, psm_data);
779
116
    }
780
781
116
    if (l2cap_data) {
782
116
        proto_item        *sub_item;
783
116
        uint32_t           bt_uuid = 0;
784
116
        uint32_t           disconnect_in_frame = 0;
785
116
        psm_data_t        *psm_data;
786
116
        wmem_tree_key_t    key[6];
787
116
        uint32_t           k_interface_id;
788
116
        uint32_t           k_adapter_id;
789
116
        uint32_t           k_chandle;
790
116
        uint32_t           k_cid;
791
116
        uint32_t           k_frame_number;
792
116
        uint32_t           interface_id;
793
116
        uint32_t           adapter_id;
794
116
        uint32_t           chandle;
795
796
116
        if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID)
797
0
            interface_id = pinfo->rec->rec_header.packet_header.interface_id;
798
116
        else
799
116
            interface_id = HCI_INTERFACE_DEFAULT;
800
116
        adapter_id   = (acl_data) ? acl_data->adapter_id : HCI_ADAPTER_DEFAULT;
801
116
        chandle      = (acl_data) ? acl_data->chandle : 0;
802
803
116
        k_interface_id = interface_id;
804
116
        k_adapter_id   = adapter_id;
805
116
        k_chandle      = chandle;
806
116
        k_cid          = scid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x80000000 : 0x00000000);
807
116
        k_frame_number = pinfo->num;
808
809
116
        key[0].length = 1;
810
116
        key[0].key    = &k_interface_id;
811
116
        key[1].length = 1;
812
116
        key[1].key    = &k_adapter_id;
813
116
        key[2].length = 1;
814
116
        key[2].key    = &k_chandle;
815
116
        key[3].length = 1;
816
116
        key[3].key    = &k_cid;
817
116
        key[4].length = 1;
818
116
        key[4].key    = &k_frame_number;
819
116
        key[5].length = 0;
820
116
        key[5].key    = NULL;
821
822
116
        psm_data = (psm_data_t *)wmem_tree_lookup32_array_le(cid_to_psm_table, key);
823
116
        if (psm_data &&
824
116
            psm_data->interface_id == interface_id &&
825
116
            psm_data->adapter_id == adapter_id &&
826
116
            psm_data->chandle == chandle &&
827
116
            psm_data->local_cid == k_cid)
828
116
        {
829
116
            bt_uuid = get_service_uuid(pinfo, l2cap_data, psm_data->psm, psm_data->local_service);
830
116
            disconnect_in_frame = psm_data->disconnect_in_frame;
831
116
        }
832
833
116
        if (bt_uuid) {
834
0
            sub_item = proto_tree_add_uint(tree, hf_btl2cap_service, tvb, 0, 0, bt_uuid);
835
0
            proto_item_set_generated(sub_item);
836
0
        }
837
838
116
        if (disconnect_in_frame < bluetooth_max_disconnect_in_frame) {
839
0
            sub_item = proto_tree_add_uint(tree, hf_btl2cap_disconnect_in_frame, tvb, 0, 0, disconnect_in_frame);
840
0
            proto_item_set_generated(sub_item);
841
0
        }
842
116
    }
843
844
116
    return offset;
845
116
}
846
static int
847
dissect_le_credit_based_connrequest(tvbuff_t *tvb, int offset, packet_info *pinfo,
848
    proto_tree *tree, proto_tree *command_tree, uint16_t cid, uint8_t cmd_ident,
849
    bthci_acl_data_t *acl_data, btl2cap_data_t *l2cap_data)
850
289
{
851
852
289
    proto_item  *psm_item;
853
289
    uint32_t     psm;
854
289
    uint32_t     scid;
855
856
857
289
    proto_tree_add_item_ret_uint(command_tree, hf_btl2cap_le_psm, tvb, offset, 2, ENC_LITTLE_ENDIAN, &psm);
858
289
    if (psm < 0x80) {
859
44
        psm_item = proto_tree_add_item(command_tree, hf_btl2cap_psm, tvb, offset, 2, ENC_LITTLE_ENDIAN);
860
44
        proto_item_set_generated(psm_item);
861
44
    }
862
289
    offset += 2;
863
864
289
    proto_tree_add_item_ret_uint(command_tree, hf_btl2cap_scid, tvb, offset, 2, ENC_LITTLE_ENDIAN, &scid);
865
289
    offset += 2;
866
867
289
    proto_tree_add_item(command_tree, hf_btl2cap_option_mtu, tvb, offset, 2, ENC_LITTLE_ENDIAN);
868
289
    offset += 2;
869
870
289
    proto_tree_add_item(command_tree, hf_btl2cap_option_mps, tvb, offset, 2, ENC_LITTLE_ENDIAN);
871
289
    offset += 2;
872
873
289
    proto_tree_add_item(command_tree, hf_btl2cap_initial_credits, tvb, offset, 2, ENC_LITTLE_ENDIAN);
874
289
    offset += 2;
875
876
289
    if (!pinfo->fd->visited) {
877
284
        wmem_tree_key_t    key[8];
878
284
        uint32_t           k_interface_id;
879
284
        uint32_t           k_adapter_id;
880
284
        uint32_t           k_chandle;
881
284
        uint32_t           k_cid;
882
284
        uint32_t           k_cmd_ident;
883
284
        uint32_t           k_frame_number;
884
284
        uint32_t           interface_id;
885
284
        uint32_t           adapter_id;
886
284
        uint32_t           chandle;
887
284
        psm_data_t        *psm_data;
888
284
        uint32_t           key_cid;
889
284
        uint32_t           cid_index;
890
891
284
        if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID)
892
0
            interface_id = pinfo->rec->rec_header.packet_header.interface_id;
893
284
        else
894
284
            interface_id = HCI_INTERFACE_DEFAULT;
895
284
        adapter_id = (acl_data) ? acl_data->adapter_id : HCI_ADAPTER_DEFAULT;
896
284
        chandle = (acl_data) ? acl_data->chandle : 0;
897
898
284
        k_interface_id = interface_id;
899
284
        k_adapter_id = adapter_id;
900
284
        k_chandle = chandle;
901
284
        k_cid = cid;
902
284
        k_cmd_ident = cmd_ident;
903
284
        k_frame_number = pinfo->num;
904
284
        cid_index = 0;
905
906
284
        psm_data = wmem_new0(wmem_file_scope(), psm_data_t);
907
908
284
        if (pinfo->p2p_dir == P2P_DIR_RECV) {
909
0
            key_cid = scid | 0x80000000;
910
0
            psm_data->local_cid = BTL2CAP_UNKNOWN_CID;
911
0
            psm_data->remote_cid = key_cid;
912
0
        }
913
284
        else {
914
284
            key_cid = scid;
915
284
            psm_data->local_cid = key_cid;
916
284
            psm_data->remote_cid = BTL2CAP_UNKNOWN_CID;
917
284
        }
918
919
284
        psm_data->psm = psm;
920
284
        psm_data->local_service = (pinfo->p2p_dir == P2P_DIR_RECV) ? true : false;
921
284
        psm_data->in.mode = L2CAP_LE_CREDIT_BASED_FLOW_CONTROL_MODE;
922
284
        psm_data->in.start_fragments = wmem_tree_new(wmem_file_scope());
923
284
        psm_data->out.mode = L2CAP_LE_CREDIT_BASED_FLOW_CONTROL_MODE;
924
284
        psm_data->out.start_fragments = wmem_tree_new(wmem_file_scope());
925
284
        psm_data->interface_id = k_interface_id;
926
284
        psm_data->adapter_id = k_adapter_id;
927
284
        psm_data->chandle = k_chandle;
928
284
        psm_data->connect_in_frame = pinfo->num;
929
284
        psm_data->disconnect_in_frame = bluetooth_max_disconnect_in_frame;
930
931
284
        key[0].length = 1;
932
284
        key[0].key = &k_interface_id;
933
284
        key[1].length = 1;
934
284
        key[1].key = &k_adapter_id;
935
284
        key[2].length = 1;
936
284
        key[2].key = &k_chandle;
937
284
        key[3].length = 1;
938
284
        key[3].key = &k_cid;
939
284
        key[4].length = 1;
940
284
        key[4].key = &k_cmd_ident;
941
284
        key[5].length = 1;
942
284
        key[5].key = &k_frame_number;
943
284
        key[6].length = 1;
944
284
        key[6].key = &cid_index;
945
284
        key[7].length = 0;
946
284
        key[7].key = NULL;
947
948
284
        wmem_tree_insert32_array(cmd_ident_to_psm_table, key, psm_data);
949
950
284
        k_cid = key_cid;
951
952
284
        key[4].length = 1;
953
284
        key[4].key = &k_frame_number;
954
284
        key[5].length = 0;
955
284
        key[5].key = NULL;
956
957
284
        wmem_tree_insert32_array(cid_to_psm_table, key, psm_data);
958
284
    }
959
960
289
    if (l2cap_data) {
961
284
        proto_item        *sub_item;
962
284
        uint32_t           bt_uuid = 0;
963
284
        uint32_t           disconnect_in_frame = 0;
964
284
        psm_data_t        *psm_data;
965
284
        wmem_tree_key_t    key[6];
966
284
        uint32_t           k_interface_id;
967
284
        uint32_t           k_adapter_id;
968
284
        uint32_t           k_chandle;
969
284
        uint32_t           k_cid;
970
284
        uint32_t           k_frame_number;
971
284
        uint32_t           interface_id;
972
284
        uint32_t           adapter_id;
973
284
        uint32_t           chandle;
974
975
284
        if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID)
976
0
            interface_id = pinfo->rec->rec_header.packet_header.interface_id;
977
284
        else
978
284
            interface_id = HCI_INTERFACE_DEFAULT;
979
284
        adapter_id = (acl_data) ? acl_data->adapter_id : HCI_ADAPTER_DEFAULT;
980
284
        chandle = (acl_data) ? acl_data->chandle : 0;
981
982
284
        k_interface_id = interface_id;
983
284
        k_adapter_id = adapter_id;
984
284
        k_chandle = chandle;
985
284
        k_cid = scid;
986
284
        k_frame_number = pinfo->num;
987
988
284
        key[0].length = 1;
989
284
        key[0].key = &k_interface_id;
990
284
        key[1].length = 1;
991
284
        key[1].key = &k_adapter_id;
992
284
        key[2].length = 1;
993
284
        key[2].key = &k_chandle;
994
284
        key[3].length = 1;
995
284
        key[3].key = &k_cid;
996
284
        key[4].length = 1;
997
284
        key[4].key = &k_frame_number;
998
284
        key[5].length = 0;
999
284
        key[5].key = NULL;
1000
1001
284
        psm_data = (psm_data_t *)wmem_tree_lookup32_array_le(cid_to_psm_table, key);
1002
284
        if (psm_data &&
1003
284
            psm_data->interface_id == interface_id &&
1004
284
            psm_data->adapter_id == adapter_id &&
1005
284
            psm_data->chandle == chandle &&
1006
284
            psm_data->local_cid == k_cid)
1007
284
        {
1008
284
            bt_uuid = get_service_uuid(pinfo, l2cap_data, psm_data->psm, psm_data->local_service);
1009
284
            disconnect_in_frame = psm_data->disconnect_in_frame;
1010
284
        }
1011
1012
284
        if (bt_uuid) {
1013
0
            sub_item = proto_tree_add_uint(tree, hf_btl2cap_service, tvb, 0, 0, bt_uuid);
1014
0
            proto_item_set_generated(sub_item);
1015
0
        }
1016
1017
284
        if (disconnect_in_frame < bluetooth_max_disconnect_in_frame) {
1018
0
            sub_item = proto_tree_add_uint(tree, hf_btl2cap_disconnect_in_frame, tvb, 0, 0, disconnect_in_frame);
1019
0
            proto_item_set_generated(sub_item);
1020
0
        }
1021
284
    }
1022
1023
289
    return offset;
1024
289
}
1025
1026
static int
1027
dissect_le_credit_based_connresponse(tvbuff_t *tvb, int offset, packet_info *pinfo,
1028
    proto_tree *tree, uint16_t cid, uint8_t cmd_ident, bthci_acl_data_t *acl_data)
1029
121
{
1030
121
    uint32_t           dcid;
1031
1032
121
    proto_tree_add_item_ret_uint(tree, hf_btl2cap_dcid, tvb, offset, 2, ENC_LITTLE_ENDIAN, &dcid);
1033
121
    offset += 2;
1034
1035
121
    proto_tree_add_item(tree, hf_btl2cap_option_mtu, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1036
121
    offset += 2;
1037
1038
121
    proto_tree_add_item(tree, hf_btl2cap_option_mps, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1039
121
    offset += 2;
1040
1041
121
    proto_tree_add_item(tree, hf_btl2cap_initial_credits, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1042
121
    offset += 2;
1043
1044
121
    proto_tree_add_item(tree, hf_btl2cap_le_result, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1045
121
    offset += 2;
1046
1047
1048
121
    if (pinfo->fd->visited == 0) {
1049
121
        psm_data_t        *psm_data;
1050
121
        wmem_tree_key_t    key[8];
1051
121
        uint32_t           k_interface_id;
1052
121
        uint32_t           k_adapter_id;
1053
121
        uint32_t           k_chandle;
1054
121
        uint32_t           k_cid;
1055
121
        uint32_t           k_cmd_ident;
1056
121
        uint32_t           k_frame_number;
1057
121
        uint32_t           interface_id;
1058
121
        uint32_t           adapter_id;
1059
121
        uint32_t           chandle;
1060
121
        uint32_t           key_cid;
1061
121
        uint32_t           cid_index;
1062
1063
121
        if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID)
1064
0
            interface_id = pinfo->rec->rec_header.packet_header.interface_id;
1065
121
        else
1066
121
            interface_id = HCI_INTERFACE_DEFAULT;
1067
121
        adapter_id = (acl_data) ? acl_data->adapter_id : HCI_ADAPTER_DEFAULT;
1068
121
        chandle = (acl_data) ? acl_data->chandle : 0;
1069
1070
121
        k_interface_id = interface_id;
1071
121
        k_adapter_id = adapter_id;
1072
121
        k_chandle = chandle;
1073
121
        k_cid = cid;
1074
121
        k_cmd_ident = cmd_ident;
1075
121
        k_frame_number = pinfo->num;
1076
121
        cid_index = 0;
1077
1078
121
        key[0].length = 1;
1079
121
        key[0].key = &k_interface_id;
1080
121
        key[1].length = 1;
1081
121
        key[1].key = &k_adapter_id;
1082
121
        key[2].length = 1;
1083
121
        key[2].key = &k_chandle;
1084
121
        key[3].length = 1;
1085
121
        key[3].key = &k_cid;
1086
121
        key[4].length = 1;
1087
121
        key[4].key = &k_cmd_ident;
1088
121
        key[5].length = 1;
1089
121
        key[5].key = &k_frame_number;
1090
121
        key[6].length = 1;
1091
121
        key[6].key = &cid_index;
1092
121
        key[7].length = 0;
1093
121
        key[7].key = NULL;
1094
1095
121
        psm_data = (psm_data_t *)wmem_tree_lookup32_array_le(cmd_ident_to_psm_table, key);
1096
121
        if (psm_data &&
1097
115
            psm_data->interface_id == interface_id &&
1098
115
            psm_data->adapter_id == adapter_id &&
1099
115
            psm_data->chandle == chandle &&
1100
115
            psm_data->disconnect_in_frame > pinfo->num)
1101
110
        {
1102
110
            key_cid = dcid | ((pinfo->p2p_dir != P2P_DIR_RECV) ? 0x00000000 : 0x80000000);
1103
1104
110
            k_interface_id = interface_id;
1105
110
            k_adapter_id = adapter_id;
1106
110
            k_chandle = chandle;
1107
110
            k_cid = key_cid;
1108
110
            k_frame_number = pinfo->num;
1109
1110
110
            key[0].length = 1;
1111
110
            key[0].key = &k_interface_id;
1112
110
            key[1].length = 1;
1113
110
            key[1].key = &k_adapter_id;
1114
110
            key[2].length = 1;
1115
110
            key[2].key = &k_chandle;
1116
110
            key[3].length = 1;
1117
110
            key[3].key = &k_cid;
1118
110
            key[4].length = 1;
1119
110
            key[4].key = &k_frame_number;
1120
110
            key[5].length = 0;
1121
110
            key[5].key = NULL;
1122
1123
110
            if (pinfo->p2p_dir == P2P_DIR_RECV)
1124
0
                psm_data->remote_cid = key_cid;
1125
110
            else
1126
110
                psm_data->local_cid = key_cid;
1127
1128
110
            wmem_tree_insert32_array(cid_to_psm_table, key, psm_data);
1129
110
        }
1130
121
    }
1131
1132
121
    return offset;
1133
121
}
1134
static int
1135
dissect_l2cap_credit_based_connrequest(tvbuff_t *tvb, int offset, packet_info *pinfo,
1136
    proto_tree *tree, proto_tree *command_tree, uint16_t cid, uint8_t cmd_ident,
1137
    uint16_t length, bthci_acl_data_t *acl_data, btl2cap_data_t *l2cap_data)
1138
42
{
1139
1140
42
    proto_item  *psm_item;
1141
42
    uint32_t     psm;
1142
42
    uint32_t     scid;
1143
42
    uint32_t     cid_index;
1144
1145
42
    proto_tree_add_item_ret_uint(command_tree, hf_btl2cap_le_psm, tvb, offset, 2, ENC_LITTLE_ENDIAN, &psm);
1146
42
    if (psm < 0x80) {
1147
18
        psm_item = proto_tree_add_item(command_tree, hf_btl2cap_psm, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1148
18
        proto_item_set_generated(psm_item);
1149
18
    }
1150
42
    offset += 2;
1151
1152
42
    proto_tree_add_item(command_tree, hf_btl2cap_option_mtu, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1153
42
    offset += 2;
1154
1155
42
    proto_tree_add_item(command_tree, hf_btl2cap_option_mps, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1156
42
    offset += 2;
1157
1158
42
    proto_tree_add_item(command_tree, hf_btl2cap_initial_credits, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1159
42
    offset += 2;
1160
1161
42
    cid_index = 0;
1162
3.18k
    while (offset < length + 8) {
1163
3.14k
        proto_tree_add_item_ret_uint(command_tree, hf_btl2cap_scid, tvb, offset, 2, ENC_LITTLE_ENDIAN, &scid);
1164
3.14k
        offset += 2;
1165
1166
3.14k
        if (!pinfo->fd->visited) {
1167
3.10k
            wmem_tree_key_t    key[8];
1168
3.10k
            uint32_t           k_interface_id;
1169
3.10k
            uint32_t           k_adapter_id;
1170
3.10k
            uint32_t           k_chandle;
1171
3.10k
            uint32_t           k_cid;
1172
3.10k
            uint32_t           k_cmd_ident;
1173
3.10k
            uint32_t           k_frame_number;
1174
3.10k
            uint32_t           interface_id;
1175
3.10k
            uint32_t           adapter_id;
1176
3.10k
            uint32_t           chandle;
1177
3.10k
            psm_data_t        *psm_data;
1178
3.10k
            uint32_t           key_cid;
1179
1180
3.10k
            if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID)
1181
0
                interface_id = pinfo->rec->rec_header.packet_header.interface_id;
1182
3.10k
            else
1183
3.10k
                interface_id = HCI_INTERFACE_DEFAULT;
1184
3.10k
            adapter_id = (acl_data) ? acl_data->adapter_id : HCI_ADAPTER_DEFAULT;
1185
3.10k
            chandle = (acl_data) ? acl_data->chandle : 0;
1186
1187
3.10k
            k_interface_id = interface_id;
1188
3.10k
            k_adapter_id = adapter_id;
1189
3.10k
            k_chandle = chandle;
1190
3.10k
            k_cid = cid;
1191
3.10k
            k_cmd_ident = cmd_ident;
1192
3.10k
            k_frame_number = pinfo->num;
1193
1194
3.10k
            psm_data = wmem_new0(wmem_file_scope(), psm_data_t);
1195
1196
3.10k
            if (pinfo->p2p_dir == P2P_DIR_RECV) {
1197
0
                key_cid = scid | 0x80000000;
1198
0
                psm_data->local_cid = BTL2CAP_UNKNOWN_CID;
1199
0
                psm_data->remote_cid = key_cid;
1200
0
            }
1201
3.10k
            else {
1202
3.10k
                key_cid = scid;
1203
3.10k
                psm_data->local_cid = key_cid;
1204
3.10k
                psm_data->remote_cid = BTL2CAP_UNKNOWN_CID;
1205
3.10k
            }
1206
1207
3.10k
            psm_data->psm = psm;
1208
3.10k
            psm_data->local_service = (pinfo->p2p_dir == P2P_DIR_RECV) ? true : false;
1209
3.10k
            psm_data->in.mode = L2CAP_LE_CREDIT_BASED_FLOW_CONTROL_MODE;
1210
3.10k
            psm_data->in.start_fragments = wmem_tree_new(wmem_file_scope());
1211
3.10k
            psm_data->out.mode = L2CAP_LE_CREDIT_BASED_FLOW_CONTROL_MODE;
1212
3.10k
            psm_data->out.start_fragments = wmem_tree_new(wmem_file_scope());
1213
3.10k
            psm_data->interface_id = k_interface_id;
1214
3.10k
            psm_data->adapter_id = k_adapter_id;
1215
3.10k
            psm_data->chandle = k_chandle;
1216
3.10k
            psm_data->connect_in_frame = pinfo->num;
1217
3.10k
            psm_data->disconnect_in_frame = bluetooth_max_disconnect_in_frame;
1218
1219
3.10k
            key[0].length = 1;
1220
3.10k
            key[0].key = &k_interface_id;
1221
3.10k
            key[1].length = 1;
1222
3.10k
            key[1].key = &k_adapter_id;
1223
3.10k
            key[2].length = 1;
1224
3.10k
            key[2].key = &k_chandle;
1225
3.10k
            key[3].length = 1;
1226
3.10k
            key[3].key = &k_cid;
1227
3.10k
            key[4].length = 1;
1228
3.10k
            key[4].key = &k_cmd_ident;
1229
3.10k
            key[5].length = 1;
1230
3.10k
            key[5].key = &k_frame_number;
1231
3.10k
            key[6].length = 1;
1232
3.10k
            key[6].key = &cid_index;
1233
3.10k
            key[7].length = 0;
1234
3.10k
            key[7].key = NULL;
1235
1236
3.10k
            wmem_tree_insert32_array(cmd_ident_to_psm_table, key, psm_data);
1237
1238
3.10k
            k_cid = key_cid;
1239
1240
3.10k
            key[4].length = 1;
1241
3.10k
            key[4].key = &k_frame_number;
1242
3.10k
            key[5].length = 0;
1243
3.10k
            key[5].key = NULL;
1244
1245
3.10k
            wmem_tree_insert32_array(cid_to_psm_table, key, psm_data);
1246
3.10k
        }
1247
1248
3.14k
        if (l2cap_data) {
1249
3.10k
            proto_item        *sub_item;
1250
3.10k
            uint32_t           bt_uuid = 0;
1251
3.10k
            uint32_t           disconnect_in_frame = 0;
1252
3.10k
            psm_data_t        *psm_data;
1253
3.10k
            wmem_tree_key_t    key[6];
1254
3.10k
            uint32_t           k_interface_id;
1255
3.10k
            uint32_t           k_adapter_id;
1256
3.10k
            uint32_t           k_chandle;
1257
3.10k
            uint32_t           k_cid;
1258
3.10k
            uint32_t           k_frame_number;
1259
3.10k
            uint32_t           interface_id;
1260
3.10k
            uint32_t           adapter_id;
1261
3.10k
            uint32_t           chandle;
1262
1263
3.10k
            if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID)
1264
0
                interface_id = pinfo->rec->rec_header.packet_header.interface_id;
1265
3.10k
            else
1266
3.10k
                interface_id = HCI_INTERFACE_DEFAULT;
1267
3.10k
            adapter_id = (acl_data) ? acl_data->adapter_id : HCI_ADAPTER_DEFAULT;
1268
3.10k
            chandle = (acl_data) ? acl_data->chandle : 0;
1269
1270
3.10k
            k_interface_id = interface_id;
1271
3.10k
            k_adapter_id = adapter_id;
1272
3.10k
            k_chandle = chandle;
1273
3.10k
            k_cid = scid;
1274
3.10k
            k_frame_number = pinfo->num;
1275
1276
3.10k
            key[0].length = 1;
1277
3.10k
            key[0].key = &k_interface_id;
1278
3.10k
            key[1].length = 1;
1279
3.10k
            key[1].key = &k_adapter_id;
1280
3.10k
            key[2].length = 1;
1281
3.10k
            key[2].key = &k_chandle;
1282
3.10k
            key[3].length = 1;
1283
3.10k
            key[3].key = &k_cid;
1284
3.10k
            key[4].length = 1;
1285
3.10k
            key[4].key = &k_frame_number;
1286
3.10k
            key[5].length = 0;
1287
3.10k
            key[5].key = NULL;
1288
1289
3.10k
            psm_data = (psm_data_t *)wmem_tree_lookup32_array_le(cid_to_psm_table, key);
1290
3.10k
            if (psm_data &&
1291
3.10k
                psm_data->interface_id == interface_id &&
1292
3.10k
                psm_data->adapter_id == adapter_id &&
1293
3.10k
                psm_data->chandle == chandle &&
1294
3.10k
                psm_data->local_cid == k_cid)
1295
3.10k
            {
1296
3.10k
                bt_uuid = get_service_uuid(pinfo, l2cap_data, psm_data->psm, psm_data->local_service);
1297
3.10k
                disconnect_in_frame = psm_data->disconnect_in_frame;
1298
3.10k
            }
1299
1300
3.10k
            if (bt_uuid) {
1301
0
                sub_item = proto_tree_add_uint(tree, hf_btl2cap_service, tvb, 0, 0, bt_uuid);
1302
0
                proto_item_set_generated(sub_item);
1303
0
            }
1304
1305
3.10k
            if (disconnect_in_frame < bluetooth_max_disconnect_in_frame) {
1306
0
                sub_item = proto_tree_add_uint(tree, hf_btl2cap_disconnect_in_frame, tvb, 0, 0, disconnect_in_frame);
1307
0
                proto_item_set_generated(sub_item);
1308
0
            }
1309
3.10k
        }
1310
1311
3.14k
        cid_index++;
1312
3.14k
    }
1313
42
    return offset;
1314
42
}
1315
1316
static int
1317
dissect_l2cap_credit_based_connresponse(tvbuff_t *tvb, int offset, packet_info *pinfo,
1318
    proto_tree *tree, uint16_t cid, uint8_t cmd_ident, uint16_t length,
1319
    bthci_acl_data_t *acl_data)
1320
41
{
1321
41
    uint32_t           dcid;
1322
41
    uint32_t           cid_index;
1323
1324
41
    proto_tree_add_item(tree, hf_btl2cap_option_mtu, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1325
41
    offset += 2;
1326
1327
41
    proto_tree_add_item(tree, hf_btl2cap_option_mps, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1328
41
    offset += 2;
1329
1330
41
    proto_tree_add_item(tree, hf_btl2cap_initial_credits, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1331
41
    offset += 2;
1332
1333
41
    proto_tree_add_item(tree, hf_btl2cap_le_result, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1334
41
    offset += 2;
1335
1336
41
    cid_index = 0;
1337
3.55k
    while (offset < length + 8) {
1338
3.51k
        proto_tree_add_item_ret_uint(tree, hf_btl2cap_dcid, tvb, offset, 2, ENC_LITTLE_ENDIAN, &dcid);
1339
3.51k
        offset += 2;
1340
1341
3.51k
        if (pinfo->fd->visited == 0) {
1342
3.48k
            psm_data_t        *psm_data;
1343
3.48k
            wmem_tree_key_t    key[8];
1344
3.48k
            uint32_t           k_interface_id;
1345
3.48k
            uint32_t           k_adapter_id;
1346
3.48k
            uint32_t           k_chandle;
1347
3.48k
            uint32_t           k_cid;
1348
3.48k
            uint32_t           k_cmd_ident;
1349
3.48k
            uint32_t           k_frame_number;
1350
3.48k
            uint32_t           interface_id;
1351
3.48k
            uint32_t           adapter_id;
1352
3.48k
            uint32_t           chandle;
1353
3.48k
            uint32_t           key_cid;
1354
1355
3.48k
            if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID)
1356
0
                interface_id = pinfo->rec->rec_header.packet_header.interface_id;
1357
3.48k
            else
1358
3.48k
                interface_id = HCI_INTERFACE_DEFAULT;
1359
3.48k
            adapter_id = (acl_data) ? acl_data->adapter_id : HCI_ADAPTER_DEFAULT;
1360
3.48k
            chandle = (acl_data) ? acl_data->chandle : 0;
1361
1362
3.48k
            k_interface_id = interface_id;
1363
3.48k
            k_adapter_id = adapter_id;
1364
3.48k
            k_chandle = chandle;
1365
3.48k
            k_cid = cid;
1366
3.48k
            k_cmd_ident = cmd_ident;
1367
3.48k
            k_frame_number = pinfo->num;
1368
1369
3.48k
            key[0].length = 1;
1370
3.48k
            key[0].key = &k_interface_id;
1371
3.48k
            key[1].length = 1;
1372
3.48k
            key[1].key = &k_adapter_id;
1373
3.48k
            key[2].length = 1;
1374
3.48k
            key[2].key = &k_chandle;
1375
3.48k
            key[3].length = 1;
1376
3.48k
            key[3].key = &k_cid;
1377
3.48k
            key[4].length = 1;
1378
3.48k
            key[4].key = &k_cmd_ident;
1379
3.48k
            key[5].length = 1;
1380
3.48k
            key[5].key = &k_frame_number;
1381
3.48k
            key[6].length = 1;
1382
3.48k
            key[6].key = &cid_index;
1383
3.48k
            key[7].length = 0;
1384
3.48k
            key[7].key = NULL;
1385
1386
3.48k
            psm_data = (psm_data_t *)wmem_tree_lookup32_array_le(cmd_ident_to_psm_table, key);
1387
3.48k
            if (psm_data &&
1388
3.48k
                psm_data->interface_id == interface_id &&
1389
3.48k
                psm_data->adapter_id == adapter_id &&
1390
3.48k
                psm_data->chandle == chandle &&
1391
3.48k
                psm_data->disconnect_in_frame > pinfo->num)
1392
3.32k
            {
1393
3.32k
                key_cid = dcid | ((pinfo->p2p_dir != P2P_DIR_RECV) ? 0x00000000 : 0x80000000);
1394
1395
3.32k
                k_interface_id = interface_id;
1396
3.32k
                k_adapter_id = adapter_id;
1397
3.32k
                k_chandle = chandle;
1398
3.32k
                k_cid = key_cid;
1399
3.32k
                k_frame_number = pinfo->num;
1400
1401
3.32k
                key[0].length = 1;
1402
3.32k
                key[0].key = &k_interface_id;
1403
3.32k
                key[1].length = 1;
1404
3.32k
                key[1].key = &k_adapter_id;
1405
3.32k
                key[2].length = 1;
1406
3.32k
                key[2].key = &k_chandle;
1407
3.32k
                key[3].length = 1;
1408
3.32k
                key[3].key = &k_cid;
1409
3.32k
                key[4].length = 1;
1410
3.32k
                key[4].key = &k_frame_number;
1411
3.32k
                key[5].length = 0;
1412
3.32k
                key[5].key = NULL;
1413
1414
3.32k
                if (pinfo->p2p_dir == P2P_DIR_RECV)
1415
0
                    psm_data->remote_cid = key_cid;
1416
3.32k
                else
1417
3.32k
                    psm_data->local_cid = key_cid;
1418
1419
3.32k
                wmem_tree_insert32_array(cid_to_psm_table, key, psm_data);
1420
3.32k
            }
1421
3.48k
        }
1422
3.51k
        cid_index++;
1423
3.51k
    }
1424
41
    return offset;
1425
41
}
1426
static int
1427
dissect_movechanrequest(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
1428
132
{
1429
132
    uint16_t icid;
1430
132
    uint8_t ctrl_id;
1431
1432
132
    icid = tvb_get_letohs(tvb, offset);
1433
132
    proto_tree_add_item(tree, hf_btl2cap_icid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1434
132
    offset += 2;
1435
1436
132
    ctrl_id = tvb_get_uint8(tvb, offset);
1437
132
    proto_tree_add_item(tree, hf_btl2cap_dcontroller, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1438
132
    offset += 1;
1439
1440
132
    col_append_fstr(pinfo->cinfo, COL_INFO, " (ICID: 0x%04x, move to %s)", icid,
1441
132
                    val_to_str_const(ctrl_id, ctrl_id_code_vals, "Unknown controller"));
1442
1443
132
    return offset;
1444
132
}
1445
1446
static int
1447
dissect_options(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int length, config_data_t *config_data)
1448
75
{
1449
75
    proto_item *ti_option;
1450
75
    proto_tree *ti_option_subtree;
1451
75
    uint8_t     option_type, option_length;
1452
1453
75
    if (config_data) {
1454
0
        config_data->mode     = L2CAP_BASIC_MODE;
1455
0
        config_data->txwindow = 0;
1456
0
        config_data->maxwindowsize = 0xFFFF;
1457
0
    }
1458
1459
1.35k
    while (length > 0) {
1460
1.27k
        option_type   = tvb_get_uint8(tvb, offset);
1461
1.27k
        option_length = tvb_get_uint8(tvb, offset + 1);
1462
1463
1.27k
        ti_option = proto_tree_add_none_format(tree,
1464
1.27k
                hf_btl2cap_option, tvb,
1465
1.27k
                offset, option_length + 2,
1466
1.27k
                "Option: ");
1467
1.27k
        ti_option_subtree = proto_item_add_subtree(ti_option, ett_btl2cap_option);
1468
1.27k
        proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1469
1.27k
        proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_length, tvb, offset + 1, 1, ENC_LITTLE_ENDIAN);
1470
1.27k
        offset += 2;
1471
1472
1.27k
        if (option_length != 0) {
1473
786
            switch (option_type) {
1474
92
            case 0x01: /* MTU */
1475
92
                proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_mtu, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1476
92
                offset += 2;
1477
1478
92
                proto_item_append_text(ti_option, "MTU");
1479
92
                break;
1480
1481
82
            case 0x02: /* Flush timeout */
1482
82
                proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_flushTO, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1483
82
                offset += 2;
1484
1485
82
                proto_item_append_text(ti_option, "Flush Timeout");
1486
82
                break;
1487
1488
25
            case 0x03: /* QOS */
1489
25
                proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1490
25
                offset += 1;
1491
1492
25
                proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_service_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1493
25
                offset += 1;
1494
1495
25
                proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_tokenrate, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1496
25
                offset += 4;
1497
1498
25
                proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_tokenbucketsize, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1499
25
                offset += 4;
1500
1501
25
                proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_peakbandwidth, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1502
25
                offset += 4;
1503
1504
25
                proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_latency, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1505
25
                offset += 4;
1506
1507
25
                proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_delayvariation, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1508
25
                offset += 4;
1509
1510
25
                proto_item_append_text(ti_option, "QOS");
1511
25
                break;
1512
1513
63
            case 0x04: /* Retransmission and Flow Control*/
1514
63
                if (config_data)
1515
0
                {
1516
0
                    config_data->mode     = tvb_get_uint8(tvb, offset);
1517
0
                    config_data->txwindow = tvb_get_uint8(tvb, offset + 1);
1518
0
                }
1519
63
                proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_retransmissionmode, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1520
63
                offset += 1;
1521
1522
63
                proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_txwindow, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1523
63
                offset += 1;
1524
1525
63
                proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_maxtransmit, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1526
63
                offset += 1;
1527
1528
63
                proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_retransmittimeout, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1529
63
                offset += 2;
1530
1531
63
                proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_monitortimeout, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1532
63
                offset += 2;
1533
1534
63
                proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_mps, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1535
63
                offset += 2;
1536
1537
63
                proto_item_append_text(ti_option, "Retransmission and Flow Control");
1538
63
                break;
1539
1540
81
            case 0x05: /* FCS */
1541
81
                proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_fcs, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1542
81
                offset += 1;
1543
1544
81
                proto_item_append_text(ti_option, "FCS");
1545
81
                break;
1546
1547
43
            case 0x06: /* Extended Flow Specification */
1548
43
                proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_identifier, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1549
43
                offset += 1;
1550
1551
43
                proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_service_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1552
43
                offset += 1;
1553
1554
43
                proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_sdu_size, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1555
43
                offset += 2;
1556
1557
43
                proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_sdu_arrival_time, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1558
43
                offset += 4;
1559
1560
43
                proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_access_latency, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1561
43
                offset += 4;
1562
1563
43
                proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_flush_to_us, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1564
43
                offset += 4;
1565
1566
43
                proto_item_append_text(ti_option, "Extended Flow Specification");
1567
43
                break;
1568
1569
66
            case 0x07: /* Extended Window Size */
1570
66
                if (config_data)
1571
0
                {
1572
0
                    config_data->maxwindowsize = tvb_get_letohs(tvb, offset);
1573
0
                }
1574
66
                proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_window, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1575
66
                offset += 2;
1576
1577
66
                proto_item_append_text(ti_option, "Extended Window Size");
1578
66
                break;
1579
1580
334
            default:
1581
334
                proto_item_append_text(ti_option, "unknown");
1582
334
                offset += option_length;
1583
334
                break;
1584
786
            }
1585
786
        }
1586
1.27k
        length -= (option_length + 2);
1587
1.27k
    }
1588
74
    return offset;
1589
75
}
1590
1591
1592
1593
static int
1594
dissect_configrequest(tvbuff_t *tvb, int offset, packet_info *pinfo,
1595
        proto_tree *tree, uint16_t length, bthci_acl_data_t *acl_data)
1596
42
{
1597
42
    uint16_t dcid;
1598
1599
42
    dcid = tvb_get_letohs(tvb, offset);
1600
1601
42
    proto_tree_add_item(tree, hf_btl2cap_dcid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1602
42
    offset += 2;
1603
1604
42
    col_append_fstr(pinfo->cinfo, COL_INFO, " (DCID: 0x%04x)", dcid);
1605
1606
42
    proto_tree_add_item(tree, hf_btl2cap_flags_reserved, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1607
42
    proto_tree_add_item(tree, hf_btl2cap_flags_continuation, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1608
42
    offset += 2;
1609
1610
42
    {
1611
42
        psm_data_t        *psm_data;
1612
42
        config_data_t     *config_data;
1613
42
        wmem_tree_key_t    key[6];
1614
42
        uint32_t           k_interface_id;
1615
42
        uint32_t           k_adapter_id;
1616
42
        uint32_t           k_chandle;
1617
42
        uint32_t           k_cid;
1618
42
        uint32_t           k_frame_number;
1619
42
        uint32_t           interface_id;
1620
42
        uint32_t           adapter_id;
1621
42
        uint32_t           chandle;
1622
42
        uint32_t           cid;
1623
1624
42
        if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID)
1625
0
            interface_id = pinfo->rec->rec_header.packet_header.interface_id;
1626
42
        else
1627
42
            interface_id = HCI_INTERFACE_DEFAULT;
1628
42
        adapter_id   = (acl_data) ? acl_data->adapter_id : HCI_ADAPTER_DEFAULT;
1629
42
        chandle      = (acl_data) ? acl_data->chandle : 0;
1630
42
        cid          = dcid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x00000000 : 0x80000000);
1631
1632
42
        k_interface_id = interface_id;
1633
42
        k_adapter_id   = adapter_id;
1634
42
        k_chandle      = chandle;
1635
42
        k_cid          = cid;
1636
42
        k_frame_number = pinfo->num;
1637
1638
42
        key[0].length = 1;
1639
42
        key[0].key    = &k_interface_id;
1640
42
        key[1].length = 1;
1641
42
        key[1].key    = &k_adapter_id;
1642
42
        key[2].length = 1;
1643
42
        key[2].key    = &k_chandle;
1644
42
        key[3].length = 1;
1645
42
        key[3].key    = &k_cid;
1646
42
        key[4].length = 1;
1647
42
        key[4].key    = &k_frame_number;
1648
42
        key[5].length = 0;
1649
42
        key[5].key    = NULL;
1650
1651
42
        psm_data = (psm_data_t *)wmem_tree_lookup32_array_le(cid_to_psm_table, key);
1652
42
        if (psm_data &&
1653
41
            psm_data->interface_id == interface_id &&
1654
41
            psm_data->adapter_id == adapter_id &&
1655
41
            psm_data->chandle == chandle &&
1656
41
            ((pinfo->p2p_dir == P2P_DIR_SENT && psm_data->remote_cid == cid) ||
1657
41
             (pinfo->p2p_dir == P2P_DIR_RECV && psm_data->local_cid == cid)) &&
1658
0
            psm_data->disconnect_in_frame > pinfo->num)
1659
0
        {
1660
0
            if (pinfo->p2p_dir == P2P_DIR_RECV)
1661
0
                config_data = &(psm_data->out);
1662
0
            else
1663
0
                config_data = &(psm_data->in);
1664
42
        } else {
1665
42
            config_data = NULL;
1666
42
        }
1667
42
        if (config_data != NULL) {
1668
            /* Reset config_data that might have been set by an earlier
1669
             * Configure Request that failed.
1670
             */
1671
0
            config_data->mode     = L2CAP_BASIC_MODE;
1672
0
            config_data->txwindow = 0;
1673
0
        }
1674
42
        if (tvb_reported_length_remaining(tvb, offset) > 0) {
1675
41
            offset = dissect_options(tvb, offset, pinfo, tree, length - 4, config_data);
1676
41
        }
1677
42
    }
1678
1679
42
    return offset;
1680
42
}
1681
1682
1683
static int
1684
dissect_inforequest(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
1685
18
{
1686
18
    uint16_t info_type;
1687
1688
18
    info_type = tvb_get_letohs(tvb, offset);
1689
18
    proto_tree_add_item(tree, hf_btl2cap_info_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1690
18
    offset   += 2;
1691
1692
18
    col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", val_to_str_const(info_type, info_type_vals, "Unknown type"));
1693
18
    return offset;
1694
18
}
1695
1696
static int
1697
dissect_inforesponse(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
1698
3
{
1699
3
    uint16_t    info_type, result;
1700
1701
3
    info_type = tvb_get_letohs(tvb, offset);
1702
3
    proto_tree_add_item(tree, hf_btl2cap_info_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1703
3
    offset   += 2;
1704
1705
3
    result    = tvb_get_letohs(tvb, offset);
1706
3
    proto_tree_add_item(tree, hf_btl2cap_info_result, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1707
3
    offset   += 2;
1708
1709
3
    col_append_fstr(pinfo->cinfo, COL_INFO, " (%s, %s)",
1710
3
                        val_to_str_const(info_type, info_type_vals, "Unknown type"),
1711
3
                        val_to_str_const(result, info_result_vals, "Unknown result"));
1712
1713
3
    if (tvb_reported_length_remaining(tvb, offset) > 0) {
1714
2
        proto_item *ti_features;
1715
2
        proto_tree *ti_features_subtree;
1716
2
        uint32_t    features;
1717
1718
2
        switch (info_type) {
1719
0
        case 0x0001: /* Connectionless MTU */
1720
0
            proto_tree_add_item(tree, hf_btl2cap_info_mtu, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1721
0
            offset += 2;
1722
1723
0
            break;
1724
0
        case 0x0002: /* Extended Features */
1725
0
            ti_features = proto_tree_add_none_format(tree,
1726
0
                    hf_btl2cap_info_extfeatures, tvb,
1727
0
                    offset, 4,
1728
0
                    "Features: ");
1729
0
            ti_features_subtree = proto_item_add_subtree(ti_features, ett_btl2cap_extfeatures);
1730
0
            features = tvb_get_letohl(tvb, offset);
1731
0
            if (features & 0x1)
1732
0
                proto_item_append_text(ti_features, "FlowControl ");
1733
0
            if (features & 0x2)
1734
0
                proto_item_append_text(ti_features, "Retransmission ");
1735
0
            if (features & 0x4)
1736
0
                proto_item_append_text(ti_features, "BiDirQOS ");
1737
0
            if (features & 0x8)
1738
0
                proto_item_append_text(ti_features, "EnhRetransmission ");
1739
0
            if (features & 0x10)
1740
0
                proto_item_append_text(ti_features, "Streaming ");
1741
0
            if (features & 0x20)
1742
0
                proto_item_append_text(ti_features, "FCS ");
1743
0
            if (features & 0x40)
1744
0
                proto_item_append_text(ti_features, "FlowSpec ");
1745
0
            if (features & 0x80)
1746
0
                proto_item_append_text(ti_features, "FixedChan ");
1747
0
            if (features & 0x100)
1748
0
                proto_item_append_text(ti_features, "WindowSize ");
1749
0
            if (features & 0x200)
1750
0
                proto_item_append_text(ti_features, "Unicast ");
1751
0
            proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_flowcontrol,         tvb, offset, 4, ENC_LITTLE_ENDIAN);
1752
0
            proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_retransmission,      tvb, offset, 4, ENC_LITTLE_ENDIAN);
1753
0
            proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_bidirqos,            tvb, offset, 4, ENC_LITTLE_ENDIAN);
1754
0
            proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_enh_retransmission,  tvb, offset, 4, ENC_LITTLE_ENDIAN);
1755
0
            proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_streaming,           tvb, offset, 4, ENC_LITTLE_ENDIAN);
1756
0
            proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_fcs,                 tvb, offset, 4, ENC_LITTLE_ENDIAN);
1757
0
            proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_flow_spec,           tvb, offset, 4, ENC_LITTLE_ENDIAN);
1758
0
            proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_fixedchan,           tvb, offset, 4, ENC_LITTLE_ENDIAN);
1759
0
            proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_window,              tvb, offset, 4, ENC_LITTLE_ENDIAN);
1760
0
            proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_unicast,             tvb, offset, 4, ENC_LITTLE_ENDIAN);
1761
0
            offset += 4;
1762
1763
0
            break;
1764
1765
0
        case 0x0003: /* Fixed Channels Supported */
1766
0
            ti_features = proto_tree_add_none_format(tree,
1767
0
                    hf_btl2cap_info_fixedchans, tvb,
1768
0
                    offset, 8,
1769
0
                    "Fixed Channels Supported:");
1770
0
            ti_features_subtree = proto_item_add_subtree(ti_features, ett_btl2cap_fixedchans);
1771
0
            proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_fixedchans_null,     tvb, offset, 4, ENC_LITTLE_ENDIAN);
1772
0
            proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_fixedchans_signal,   tvb, offset, 4, ENC_LITTLE_ENDIAN);
1773
0
            proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_fixedchans_connless, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1774
0
            proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_fixedchans_amp_man,  tvb, offset, 4, ENC_LITTLE_ENDIAN);
1775
0
            proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_fixedchans_rfu,  tvb, offset, 4, ENC_LITTLE_ENDIAN);
1776
0
            proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_fixedchans_smp,  tvb, offset, 4, ENC_LITTLE_ENDIAN);
1777
0
            offset += 4;
1778
0
            proto_tree_add_item(ti_features_subtree, hf_btl2cap_info_fixedchans_amp_test, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1779
0
            offset += 4;
1780
1781
0
            break;
1782
1783
2
        default:
1784
2
            proto_tree_add_item(tree, hf_btl2cap_cmd_data, tvb, offset, -1, ENC_NA);
1785
2
            offset += tvb_reported_length_remaining(tvb, offset);
1786
1787
2
            break;
1788
2
        }
1789
2
    }
1790
1791
3
    return offset;
1792
3
}
1793
1794
static int
1795
dissect_configresponse(tvbuff_t *tvb, int offset, packet_info *pinfo,
1796
        proto_tree *tree, uint16_t length, bthci_acl_data_t *acl_data)
1797
34
{
1798
34
    uint16_t           scid;
1799
34
    uint16_t           result;
1800
1801
1802
34
    scid = tvb_get_letohs(tvb, offset);
1803
1804
34
    proto_tree_add_item(tree, hf_btl2cap_scid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1805
34
    offset += 2;
1806
1807
34
    proto_tree_add_item(tree, hf_btl2cap_flags_reserved, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1808
34
    proto_tree_add_item(tree, hf_btl2cap_flags_continuation, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1809
34
    offset += 2;
1810
1811
34
    result = tvb_get_letohs(tvb, offset);
1812
34
    proto_tree_add_item(tree, hf_btl2cap_configuration_result, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1813
34
    offset += 2;
1814
1815
34
    col_append_fstr(pinfo->cinfo, COL_INFO, " - %s (SCID: 0x%04x)",
1816
34
                    val_to_str_const(result, configuration_result_vals, "Unknown"), scid);
1817
1818
34
    if (tvb_reported_length_remaining(tvb, offset) > 0) {
1819
34
        psm_data_t        *psm_data;
1820
34
        config_data_t     *config_data;
1821
34
        wmem_tree_key_t    key[6];
1822
34
        uint32_t           k_interface_id;
1823
34
        uint32_t           k_adapter_id;
1824
34
        uint32_t           k_chandle;
1825
34
        uint32_t           k_cid;
1826
34
        uint32_t           k_frame_number;
1827
34
        uint32_t           interface_id;
1828
34
        uint32_t           adapter_id;
1829
34
        uint32_t           chandle;
1830
34
        uint32_t           cid;
1831
1832
34
        if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID)
1833
0
            interface_id = pinfo->rec->rec_header.packet_header.interface_id;
1834
34
        else
1835
34
            interface_id = HCI_INTERFACE_DEFAULT;
1836
34
        adapter_id   = (acl_data) ? acl_data->adapter_id : HCI_ADAPTER_DEFAULT;
1837
34
        chandle      = (acl_data) ? acl_data->chandle : 0;
1838
34
        cid          = scid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x00000000 : 0x80000000);
1839
1840
34
        k_interface_id = interface_id;
1841
34
        k_adapter_id   = adapter_id;
1842
34
        k_chandle      = chandle;
1843
34
        k_cid          = cid;
1844
34
        k_frame_number = pinfo->num;
1845
1846
34
        key[0].length = 1;
1847
34
        key[0].key    = &k_interface_id;
1848
34
        key[1].length = 1;
1849
34
        key[1].key    = &k_adapter_id;
1850
34
        key[2].length = 1;
1851
34
        key[2].key    = &k_chandle;
1852
34
        key[3].length = 1;
1853
34
        key[3].key    = &k_cid;
1854
34
        key[4].length = 1;
1855
34
        key[4].key    = &k_frame_number;
1856
34
        key[5].length = 0;
1857
34
        key[5].key    = NULL;
1858
1859
34
        psm_data = (psm_data_t *)wmem_tree_lookup32_array_le(cid_to_psm_table, key);
1860
34
        if (psm_data &&
1861
34
            psm_data->interface_id == interface_id &&
1862
34
            psm_data->adapter_id == adapter_id &&
1863
34
            psm_data->chandle == chandle &&
1864
34
            ((pinfo->p2p_dir == P2P_DIR_SENT && psm_data->local_cid == cid) ||
1865
34
             (pinfo->p2p_dir == P2P_DIR_RECV && psm_data->remote_cid == cid)) &&
1866
0
            psm_data->disconnect_in_frame > pinfo->num)
1867
0
        {
1868
0
            if (pinfo->p2p_dir == P2P_DIR_RECV)
1869
0
                config_data = &(psm_data->out);
1870
0
            else
1871
0
                config_data = &(psm_data->in);
1872
34
        } else {
1873
34
            config_data = NULL;
1874
34
        }
1875
34
        offset = dissect_options(tvb, offset, pinfo, tree, length - 6, config_data);
1876
34
    }
1877
1878
34
    return offset;
1879
34
}
1880
1881
static int
1882
dissect_connresponse(tvbuff_t *tvb, int offset, packet_info *pinfo,
1883
        proto_tree *tree, bthci_acl_data_t *acl_data)
1884
39
{
1885
39
    uint16_t           scid, dcid, result;
1886
1887
39
    dcid = tvb_get_letohs(tvb, offset);
1888
39
    proto_tree_add_item(tree, hf_btl2cap_dcid,   tvb, offset, 2, ENC_LITTLE_ENDIAN);
1889
39
    offset += 2;
1890
1891
39
    scid = tvb_get_letohs(tvb, offset);
1892
39
    proto_tree_add_item(tree, hf_btl2cap_scid,   tvb, offset, 2, ENC_LITTLE_ENDIAN);
1893
39
    offset += 2;
1894
1895
39
    result = tvb_get_letohs(tvb, offset);
1896
39
    proto_tree_add_item(tree, hf_btl2cap_result, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1897
39
    offset += 2;
1898
1899
39
    proto_tree_add_item(tree, hf_btl2cap_status, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1900
39
    offset += 2;
1901
1902
39
    if (result == 0) {
1903
1
        col_append_fstr(pinfo->cinfo, COL_INFO, " - Success (SCID: 0x%04x, DCID: 0x%04x)", scid, dcid);
1904
1
    }
1905
38
    else {
1906
38
        col_append_fstr(pinfo->cinfo, COL_INFO, " - %s (SCID: 0x%04x)",
1907
38
                        val_to_str_const(result, result_vals, "Unknown"), scid);
1908
38
    }
1909
1910
39
    if (pinfo->fd->visited == 0) {
1911
37
        psm_data_t        *psm_data;
1912
37
        wmem_tree_key_t    key[6];
1913
37
        uint32_t           k_interface_id;
1914
37
        uint32_t           k_adapter_id;
1915
37
        uint32_t           k_chandle;
1916
37
        uint32_t           k_cid;
1917
37
        uint32_t           k_frame_number;
1918
37
        uint32_t           interface_id;
1919
37
        uint32_t           adapter_id;
1920
37
        uint32_t           chandle;
1921
37
        uint32_t           cid;
1922
1923
37
        if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID)
1924
0
            interface_id = pinfo->rec->rec_header.packet_header.interface_id;
1925
37
        else
1926
37
            interface_id = HCI_INTERFACE_DEFAULT;
1927
37
        adapter_id   = (acl_data) ? acl_data->adapter_id : HCI_ADAPTER_DEFAULT;
1928
37
        chandle      = (acl_data) ? acl_data->chandle : 0;
1929
37
        cid          = scid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x00000000 : 0x80000000);
1930
1931
37
        k_interface_id = interface_id;
1932
37
        k_adapter_id   = adapter_id;
1933
37
        k_chandle      = chandle;
1934
37
        k_cid          = cid;
1935
37
        k_frame_number = pinfo->num;
1936
1937
37
        key[0].length = 1;
1938
37
        key[0].key    = &k_interface_id;
1939
37
        key[1].length = 1;
1940
37
        key[1].key    = &k_adapter_id;
1941
37
        key[2].length = 1;
1942
37
        key[2].key    = &k_chandle;
1943
37
        key[3].length = 1;
1944
37
        key[3].key    = &k_cid;
1945
37
        key[4].length = 1;
1946
37
        key[4].key    = &k_frame_number;
1947
37
        key[5].length = 0;
1948
37
        key[5].key    = NULL;
1949
1950
37
        psm_data = (psm_data_t *)wmem_tree_lookup32_array_le(cid_to_psm_table, key);
1951
37
        if (psm_data &&
1952
37
            psm_data->interface_id == interface_id &&
1953
37
            psm_data->adapter_id == adapter_id &&
1954
37
            psm_data->chandle == chandle &&
1955
37
            ((pinfo->p2p_dir == P2P_DIR_SENT && psm_data->remote_cid == cid) ||
1956
37
             (pinfo->p2p_dir == P2P_DIR_RECV && psm_data->local_cid == cid)) &&
1957
0
            psm_data->disconnect_in_frame > pinfo->num)
1958
0
        {
1959
0
            cid = dcid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x80000000 : 0x00000000);
1960
1961
0
            k_interface_id = interface_id;
1962
0
            k_adapter_id   = adapter_id;
1963
0
            k_chandle      = chandle;
1964
0
            k_cid          = cid;
1965
0
            k_frame_number = pinfo->num;
1966
1967
0
            key[0].length = 1;
1968
0
            key[0].key    = &k_interface_id;
1969
0
            key[1].length = 1;
1970
0
            key[1].key    = &k_adapter_id;
1971
0
            key[2].length = 1;
1972
0
            key[2].key    = &k_chandle;
1973
0
            key[3].length = 1;
1974
0
            key[3].key    = &k_cid;
1975
0
            key[4].length = 1;
1976
0
            key[4].key    = &k_frame_number;
1977
0
            key[5].length = 0;
1978
0
            key[5].key    = NULL;
1979
1980
0
            if (pinfo->p2p_dir == P2P_DIR_RECV)
1981
0
                psm_data->remote_cid = cid;
1982
0
            else
1983
0
                psm_data->local_cid = cid;
1984
1985
0
            wmem_tree_insert32_array(cid_to_psm_table, key, psm_data);
1986
0
        }
1987
37
    }
1988
1989
39
    return offset;
1990
39
}
1991
1992
static int
1993
dissect_chanresponse(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, bthci_acl_data_t *acl_data)
1994
14
{
1995
14
    return dissect_connresponse(tvb, offset, pinfo, tree, acl_data);
1996
14
}
1997
1998
static int
1999
dissect_movechanresponse(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
2000
30
{
2001
30
    uint16_t icid, result;
2002
2003
30
    icid = tvb_get_letohs(tvb, offset);
2004
30
    proto_tree_add_item(tree, hf_btl2cap_icid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2005
30
    offset += 2;
2006
2007
30
    result = tvb_get_letohs(tvb, offset);
2008
30
    proto_tree_add_item(tree, hf_btl2cap_move_result, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2009
30
    offset += 2;
2010
2011
30
    col_append_fstr(pinfo->cinfo, COL_INFO, " (ICID: 0x%04x, %s)", icid,
2012
30
                    val_to_str_const(result, move_result_vals, "Unknown result"));
2013
2014
30
    return offset;
2015
30
}
2016
2017
static int
2018
dissect_movechanconfirmation(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
2019
92
{
2020
92
    uint16_t icid, result;
2021
2022
92
    icid = tvb_get_letohs(tvb, offset);
2023
92
    proto_tree_add_item(tree, hf_btl2cap_icid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2024
92
    offset += 2;
2025
2026
92
    result = tvb_get_letohs(tvb, offset);
2027
92
    proto_tree_add_item(tree, hf_btl2cap_move_confirmation_result, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2028
92
    offset += 2;
2029
2030
92
    col_append_fstr(pinfo->cinfo, COL_INFO, " (ICID: 0x%04x, %s)", icid,
2031
92
                    val_to_str_const(result, move_result_confirmation_vals, "Unknown result"));
2032
2033
92
    return offset;
2034
92
}
2035
2036
static int
2037
dissect_movechanconfirmationresponse(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
2038
164
{
2039
164
    uint16_t icid;
2040
2041
164
    icid = tvb_get_letohs(tvb, offset);
2042
164
    proto_tree_add_item(tree, hf_btl2cap_icid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2043
164
    offset += 2;
2044
2045
164
    col_append_fstr(pinfo->cinfo, COL_INFO, " (ICID: 0x%04x)", icid);
2046
164
    return offset;
2047
164
}
2048
2049
static int
2050
dissect_connparamrequest(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
2051
30
{
2052
30
    proto_item *item;
2053
30
    uint16_t max_interval, peripheral_latency;
2054
2055
30
    item = proto_tree_add_item(tree, hf_btl2cap_min_interval, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2056
30
    proto_item_append_text(item, " (%g msec)",  tvb_get_letohs(tvb, offset) * 1.25);
2057
30
    offset += 2;
2058
30
    item = proto_tree_add_item(tree, hf_btl2cap_max_interval, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2059
30
    proto_item_append_text(item, " (%g msec)",  tvb_get_letohs(tvb, offset) * 1.25);
2060
30
    max_interval = tvb_get_letohs(tvb, offset);
2061
30
    offset += 2;
2062
30
    item = proto_tree_add_item(tree, hf_btl2cap_peripheral_latency, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2063
30
    peripheral_latency = tvb_get_letohs(tvb, offset);
2064
2065
30
    if(peripheral_latency >= 500 || max_interval == 0 ||
2066
4
       peripheral_latency > 10.0 * tvb_get_letohs(tvb, offset + 2) / (max_interval *1.25))
2067
26
        expert_add_info(pinfo, item, &ei_btl2cap_parameter_mismatch);
2068
2069
30
    offset += 2;
2070
30
    item = proto_tree_add_item(tree, hf_btl2cap_timeout_multiplier, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2071
30
    proto_item_append_text(item, " (%g sec)",  tvb_get_letohs(tvb, offset) * 0.01);
2072
30
    offset += 2;
2073
2074
30
    return offset;
2075
30
}
2076
2077
static int
2078
dissect_connparamresponse(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
2079
29
{
2080
29
    uint16_t result;
2081
2082
29
    result = tvb_get_letohs(tvb, offset);
2083
29
    proto_tree_add_item(tree, hf_btl2cap_conn_param_result, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2084
29
    offset += 2;
2085
2086
29
    col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)",
2087
29
                    val_to_str_const(result, conn_param_result_vals, "Unknown result"));
2088
2089
29
    return offset;
2090
29
}
2091
2092
static int
2093
dissect_disconnrequestresponse(tvbuff_t *tvb, int offset, packet_info *pinfo,
2094
        proto_tree *tree, proto_tree *command_tree, bthci_acl_data_t *acl_data, btl2cap_data_t *l2cap_data,
2095
        bool is_request)
2096
356
{
2097
356
    uint16_t      scid;
2098
356
    uint16_t      dcid;
2099
356
    unsigned      psm = 0;
2100
356
    const char   *service_name = "Unknown";
2101
2102
356
    dcid = tvb_get_letohs(tvb, offset);
2103
356
    proto_tree_add_item(command_tree, hf_btl2cap_dcid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2104
356
    offset += 2;
2105
2106
356
    scid = tvb_get_letohs(tvb, offset);
2107
356
    proto_tree_add_item(command_tree, hf_btl2cap_scid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2108
356
    offset += 2;
2109
2110
356
    if (!pinfo->fd->visited) {
2111
354
        psm_data_t        *psm_data;
2112
354
        wmem_tree_key_t    key[6];
2113
354
        uint32_t           k_interface_id;
2114
354
        uint32_t           k_adapter_id;
2115
354
        uint32_t           k_chandle;
2116
354
        uint32_t           k_cid;
2117
354
        uint32_t           k_frame_number;
2118
354
        uint32_t           interface_id;
2119
354
        uint32_t           adapter_id;
2120
354
        uint32_t           chandle;
2121
354
        uint32_t           key_scid;
2122
354
        uint32_t           key_dcid;
2123
2124
354
        if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID)
2125
0
            interface_id = pinfo->rec->rec_header.packet_header.interface_id;
2126
354
        else
2127
354
            interface_id = HCI_INTERFACE_DEFAULT;
2128
354
        adapter_id   = (acl_data) ? acl_data->adapter_id : HCI_ADAPTER_DEFAULT;
2129
354
        chandle      = (acl_data) ? acl_data->chandle : 0;
2130
354
        if ((is_request && pinfo->p2p_dir == P2P_DIR_SENT) ||
2131
354
                (!is_request && pinfo->p2p_dir == P2P_DIR_RECV)) {
2132
0
            key_dcid     = dcid | 0x80000000;
2133
0
            key_scid     = scid;
2134
354
        } else {
2135
354
            key_dcid     = scid | 0x80000000;
2136
354
            key_scid     = dcid;
2137
354
        }
2138
2139
354
        k_interface_id = interface_id;
2140
354
        k_adapter_id   = adapter_id;
2141
354
        k_chandle      = chandle;
2142
354
        k_cid          = key_dcid;
2143
354
        k_frame_number = pinfo->num;
2144
2145
354
        key[0].length = 1;
2146
354
        key[0].key    = &k_interface_id;
2147
354
        key[1].length = 1;
2148
354
        key[1].key    = &k_adapter_id;
2149
354
        key[2].length = 1;
2150
354
        key[2].key    = &k_chandle;
2151
354
        key[3].length = 1;
2152
354
        key[3].key    = &k_cid;
2153
354
        key[4].length = 1;
2154
354
        key[4].key    = &k_frame_number;
2155
354
        key[5].length = 0;
2156
354
        key[5].key    = NULL;
2157
2158
354
        psm_data = (psm_data_t *)wmem_tree_lookup32_array_le(cid_to_psm_table, key);
2159
354
        if (psm_data &&
2160
351
            psm_data->interface_id == interface_id &&
2161
351
            psm_data->adapter_id == adapter_id &&
2162
351
            psm_data->chandle == chandle &&
2163
351
            psm_data->remote_cid == key_dcid &&
2164
0
            psm_data->disconnect_in_frame == bluetooth_max_disconnect_in_frame)
2165
0
        {
2166
0
            psm_data->disconnect_in_frame = pinfo->num;
2167
0
        }
2168
2169
354
        k_interface_id = interface_id;
2170
354
        k_adapter_id   = adapter_id;
2171
354
        k_chandle      = chandle;
2172
354
        k_cid          = key_scid;
2173
354
        k_frame_number = pinfo->num;
2174
2175
354
        key[0].length = 1;
2176
354
        key[0].key    = &k_interface_id;
2177
354
        key[1].length = 1;
2178
354
        key[1].key    = &k_adapter_id;
2179
354
        key[2].length = 1;
2180
354
        key[2].key    = &k_chandle;
2181
354
        key[3].length = 1;
2182
354
        key[3].key    = &k_cid;
2183
354
        key[4].length = 1;
2184
354
        key[4].key    = &k_frame_number;
2185
354
        key[5].length = 0;
2186
354
        key[5].key    = NULL;
2187
2188
354
        psm_data = (psm_data_t *)wmem_tree_lookup32_array_le(cid_to_psm_table, key);
2189
354
        if (psm_data &&
2190
349
            psm_data->interface_id == interface_id &&
2191
349
            psm_data->adapter_id == adapter_id &&
2192
349
            psm_data->chandle == chandle &&
2193
349
            psm_data->local_cid == key_scid &&
2194
119
            psm_data->disconnect_in_frame == bluetooth_max_disconnect_in_frame)
2195
54
        {
2196
54
            psm_data->disconnect_in_frame = pinfo->num;
2197
54
        }
2198
354
    }
2199
2200
356
    if (l2cap_data) {
2201
354
        proto_item        *sub_item;
2202
354
        uint32_t           bt_uuid = 0;
2203
354
        uint32_t           connect_in_frame = 0;
2204
354
        psm_data_t        *psm_data;
2205
354
        wmem_tree_key_t    key[6];
2206
354
        uint32_t           k_interface_id;
2207
354
        uint32_t           k_adapter_id;
2208
354
        uint32_t           k_chandle;
2209
354
        uint32_t           k_cid;
2210
354
        uint32_t           k_frame_number;
2211
354
        uint32_t           interface_id;
2212
354
        uint32_t           adapter_id;
2213
354
        uint32_t           chandle;
2214
354
        uint32_t           key_dcid;
2215
2216
354
        if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID)
2217
0
            interface_id = pinfo->rec->rec_header.packet_header.interface_id;
2218
354
        else
2219
354
            interface_id = HCI_INTERFACE_DEFAULT;
2220
354
        adapter_id   = (acl_data) ? acl_data->adapter_id : HCI_ADAPTER_DEFAULT;
2221
354
        chandle      = (acl_data) ? acl_data->chandle : 0;
2222
354
        if ((is_request && pinfo->p2p_dir == P2P_DIR_SENT) ||
2223
354
                (!is_request && pinfo->p2p_dir == P2P_DIR_RECV)) {
2224
0
            key_dcid     = dcid | 0x80000000;
2225
354
        } else {
2226
354
            key_dcid     = scid | 0x80000000;
2227
354
        }
2228
2229
354
        k_interface_id = interface_id;
2230
354
        k_adapter_id   = adapter_id;
2231
354
        k_chandle      = chandle;
2232
354
        k_cid          = key_dcid;
2233
354
        k_frame_number = pinfo->num;
2234
2235
354
        key[0].length = 1;
2236
354
        key[0].key    = &k_interface_id;
2237
354
        key[1].length = 1;
2238
354
        key[1].key    = &k_adapter_id;
2239
354
        key[2].length = 1;
2240
354
        key[2].key    = &k_chandle;
2241
354
        key[3].length = 1;
2242
354
        key[3].key    = &k_cid;
2243
354
        key[4].length = 1;
2244
354
        key[4].key    = &k_frame_number;
2245
354
        key[5].length = 0;
2246
354
        key[5].key    = NULL;
2247
2248
354
        psm_data = (psm_data_t *)wmem_tree_lookup32_array_le(cid_to_psm_table, key);
2249
354
        if (psm_data &&
2250
351
            psm_data->interface_id == interface_id &&
2251
351
            psm_data->adapter_id == adapter_id &&
2252
351
            psm_data->chandle == chandle &&
2253
351
            psm_data->remote_cid == key_dcid)
2254
0
        {
2255
0
            psm = psm_data->psm;
2256
0
            bt_uuid = get_service_uuid(pinfo, l2cap_data, psm_data->psm, psm_data->local_service);
2257
0
            connect_in_frame = psm_data->connect_in_frame;
2258
0
        }
2259
2260
354
        if (bt_uuid) {
2261
0
            bluetooth_uuid_t   uuid;
2262
2263
0
            uuid.size = 2;
2264
0
            uuid.bt_uuid = bt_uuid;
2265
0
            uuid.data[0] = bt_uuid >> 8;
2266
0
            uuid.data[1] = bt_uuid & 0xFF;
2267
2268
0
            service_name = val_to_str_ext_const(uuid.bt_uuid, &bluetooth_uuid_vals_ext, "Unknown");
2269
0
        }
2270
2271
354
        if (strcmp(service_name, "Unknown") == 0) {
2272
354
            service_name = val_to_str_const(psm, psm_vals, "Unknown");
2273
354
        }
2274
2275
354
        if (psm > 0) {
2276
0
            sub_item = proto_tree_add_uint(tree, hf_btl2cap_psm, tvb, offset, 0, psm);
2277
0
            proto_item_set_generated(sub_item);
2278
0
        }
2279
2280
354
        if (bt_uuid) {
2281
0
            sub_item = proto_tree_add_uint(tree, hf_btl2cap_service, tvb, 0, 0, bt_uuid);
2282
0
            proto_item_set_generated(sub_item);
2283
0
        }
2284
2285
354
        if (connect_in_frame > 0) {
2286
0
            sub_item = proto_tree_add_uint(tree, hf_btl2cap_connect_in_frame, tvb, 0, 0, connect_in_frame);
2287
0
            proto_item_set_generated(sub_item);
2288
0
        }
2289
354
    }
2290
2291
356
    if (psm > 0)
2292
0
        col_append_fstr(pinfo->cinfo, COL_INFO, " (SCID: 0x%04x, DCID: 0x%04x, PSM: 0x%04x, Service: %s)", scid, dcid, psm, service_name);
2293
356
    else
2294
356
        col_append_fstr(pinfo->cinfo, COL_INFO, " (SCID: 0x%04x, DCID: 0x%04x, PSM: Unknown, Service: %s)", scid, dcid, service_name);
2295
2296
2297
356
    return offset;
2298
356
}
2299
2300
static int
2301
dissect_b_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2302
        proto_tree *btl2cap_tree, uint16_t cid, uint16_t psm,
2303
        bool is_local_psm, uint16_t length, int offset, btl2cap_data_t *l2cap_data)
2304
57
{
2305
57
    tvbuff_t *next_tvb;
2306
2307
57
    next_tvb = tvb_new_subset_length(tvb, offset, length);
2308
2309
57
    col_append_str(pinfo->cinfo, COL_INFO, "Connection oriented channel");
2310
2311
57
    if (psm) {
2312
0
        proto_item        *psm_item;
2313
0
        uint16_t           bt_uuid;
2314
0
        bluetooth_uuid_t   uuid;
2315
2316
0
        if (p_get_proto_data(pinfo->pool, pinfo, proto_btl2cap, PROTO_DATA_BTL2CAP_PSM ) == NULL) {
2317
0
            uint16_t *value_data;
2318
2319
0
            value_data = wmem_new(wmem_file_scope(), uint16_t);
2320
0
            *value_data = psm;
2321
2322
0
            p_add_proto_data(pinfo->pool, pinfo, proto_btl2cap, PROTO_DATA_BTL2CAP_PSM, value_data);
2323
0
        }
2324
2325
0
        bt_uuid = get_service_uuid(pinfo, l2cap_data, psm, is_local_psm);
2326
2327
0
        uuid.size = 2;
2328
0
        uuid.bt_uuid = bt_uuid;
2329
0
        uuid.data[0] = bt_uuid >> 8;
2330
0
        uuid.data[1] = bt_uuid & 0xFF;
2331
2332
0
        if (bt_uuid && p_get_proto_data(pinfo->pool, pinfo, proto_bluetooth, PROTO_DATA_BLUETOOTH_SERVICE_UUID) == NULL) {
2333
0
            char *value_data;
2334
2335
0
            value_data = wmem_strdup(wmem_file_scope(), print_numeric_bluetooth_uuid(pinfo->pool, &uuid));
2336
2337
0
            p_add_proto_data(pinfo->pool, pinfo, proto_bluetooth, PROTO_DATA_BLUETOOTH_SERVICE_UUID, value_data);
2338
0
        }
2339
2340
0
        if (psm < BTL2CAP_DYNAMIC_PSM_START) {
2341
0
            psm_item = proto_tree_add_uint(btl2cap_tree, hf_btl2cap_psm, tvb, offset, 0, psm);
2342
0
        }
2343
0
        else {
2344
0
            psm_item = proto_tree_add_uint(btl2cap_tree, hf_btl2cap_psm_dynamic, tvb, offset, 0, psm);
2345
0
            if (uuid.bt_uuid)
2346
0
                proto_item_append_text(psm_item, ": %s",
2347
0
                                       val_to_str_ext_const(uuid.bt_uuid, &bluetooth_uuid_vals_ext, "Unknown service"));
2348
0
        }
2349
0
        proto_item_set_generated(psm_item);
2350
2351
        /* call next dissector */
2352
0
        if (!dissector_try_uint_with_data(l2cap_cid_dissector_table, (uint32_t) cid, next_tvb, pinfo, tree, true, l2cap_data)) {
2353
0
            if (!dissector_try_uint_with_data(l2cap_psm_dissector_table, (uint32_t) psm, next_tvb, pinfo, tree, true, l2cap_data)) {
2354
                /* not a known fixed PSM, try to find a registered service to a dynamic PSM */
2355
0
                if (!dissector_try_string_with_data(bluetooth_uuid_table, print_numeric_bluetooth_uuid(pinfo->pool, &uuid), next_tvb, pinfo, tree, true,l2cap_data)) {
2356
                    /* unknown protocol. declare as data */
2357
0
                    proto_tree_add_item(btl2cap_tree, hf_btl2cap_payload, tvb, offset, length, ENC_NA);
2358
0
                }
2359
0
            }
2360
0
        }
2361
0
        offset = tvb_captured_length(tvb);
2362
57
    } else {
2363
57
        if (!dissector_try_uint_with_data(l2cap_cid_dissector_table, (uint32_t) cid, next_tvb, pinfo, tree, true, l2cap_data))
2364
57
            proto_tree_add_item(btl2cap_tree, hf_btl2cap_payload, tvb, offset, length, ENC_NA);
2365
57
        offset = tvb_captured_length(tvb);
2366
57
    }
2367
57
    return offset;
2368
57
}
2369
2370
/* An LE-frame is a PDU used in LE Credit Based Flow Control Mode. It
2371
 * contains an SDU segment and additional protocol information, encapsulated
2372
 * by a Basic L2CAP header.
2373
 */
2374
static int
2375
dissect_le_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2376
    proto_tree *btl2cap_tree, uint16_t cid, uint16_t psm, bool is_local_psm,
2377
    uint16_t length, int offset, config_data_t *config_data, btl2cap_data_t *l2cap_data,
2378
    bool is_retransmit)
2379
0
{
2380
2381
0
    tvbuff_t *new_tvb = NULL;
2382
0
    bluetooth_uuid_t   uuid;
2383
0
    btl2cap_frame_data_t *btl2cap_frame_data = NULL;
2384
0
    fragment_head *frag_btl2cap_le_sdu = NULL;
2385
2386
0
    if ((!pinfo->fd->visited) && (config_data) && !is_retransmit) {
2387
0
        btl2cap_frame_data = wmem_new0(wmem_file_scope(), btl2cap_frame_data_t);
2388
0
        if (config_data->segmentation_started == 1) {
2389
0
            config_data->segment_len_rem = config_data->segment_len_rem - length;
2390
0
            if (config_data->segment_len_rem > 0) {
2391
0
                btl2cap_frame_data->more_fragments = 1;
2392
0
            } else {
2393
0
                btl2cap_frame_data->more_fragments = 0;
2394
0
                config_data->segmentation_started = 0;
2395
0
                config_data->segment_len_rem = 0;
2396
0
            }
2397
0
        } else {
2398
            /* First Frame in this SDU, SDU length is present */
2399
0
            uint16_t sdu_length;
2400
2401
0
            sdu_length = tvb_get_letohs(tvb, offset);
2402
0
            btl2cap_frame_data->first_fragment = 1;
2403
0
            if (sdu_length == length - 2) {
2404
                /* Complete SDU no segmentation */
2405
0
                btl2cap_frame_data->more_fragments = 0;
2406
0
                config_data->segmentation_started = 0;
2407
0
                config_data->segment_len_rem = 0;
2408
0
            } else {
2409
0
                btl2cap_frame_data->more_fragments = 1;
2410
0
                config_data->segmentation_started = 1;
2411
0
                config_data->segment_len_rem = sdu_length - (length - 2);
2412
0
            }
2413
0
        }
2414
0
        p_add_proto_data(wmem_file_scope(), pinfo, proto_btl2cap, pinfo->curr_layer_num, btl2cap_frame_data);
2415
0
    } else {
2416
        /* Not the first pass */
2417
0
        btl2cap_frame_data = (btl2cap_frame_data_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_btl2cap, pinfo->curr_layer_num);
2418
0
    }
2419
2420
0
    col_append_str(pinfo->cinfo, COL_INFO, "Connection oriented channel, LE Information frame");
2421
2422
0
    if (!btl2cap_frame_data) {
2423
        /* Without frame data we do not have enough information to dissect the packet */
2424
0
        proto_tree_add_item(btl2cap_tree, hf_btl2cap_payload, tvb, offset, length, ENC_NA);
2425
0
        return tvb_captured_length(tvb);
2426
0
    }
2427
2428
2429
0
    if (psm) {
2430
0
        proto_item        *psm_item;
2431
0
        uint16_t           bt_uuid;
2432
2433
0
        if (p_get_proto_data(pinfo->pool, pinfo, proto_btl2cap, PROTO_DATA_BTL2CAP_PSM) == NULL) {
2434
0
            uint16_t *value_data;
2435
2436
0
            value_data = wmem_new(wmem_file_scope(), uint16_t);
2437
0
            *value_data = psm;
2438
2439
0
            p_add_proto_data(pinfo->pool, pinfo, proto_btl2cap, PROTO_DATA_BTL2CAP_PSM, value_data);
2440
0
        }
2441
2442
0
        bt_uuid = get_service_uuid(pinfo, l2cap_data, psm, is_local_psm);
2443
2444
0
        uuid.size = 2;
2445
0
        uuid.bt_uuid = bt_uuid;
2446
0
        uuid.data[0] = bt_uuid >> 8;
2447
0
        uuid.data[1] = bt_uuid & 0xFF;
2448
2449
0
        if (bt_uuid && p_get_proto_data(pinfo->pool, pinfo, proto_bluetooth, PROTO_DATA_BLUETOOTH_SERVICE_UUID) == NULL) {
2450
0
            char *value_data;
2451
2452
0
            value_data = wmem_strdup(wmem_file_scope(), print_numeric_bluetooth_uuid(pinfo->pool, &uuid));
2453
2454
0
            p_add_proto_data(pinfo->pool, pinfo, proto_bluetooth, PROTO_DATA_BLUETOOTH_SERVICE_UUID, value_data);
2455
0
        }
2456
2457
0
        if (psm < BTL2CAP_DYNAMIC_PSM_START) {
2458
0
            psm_item = proto_tree_add_uint(btl2cap_tree, hf_btl2cap_psm, tvb, offset, 0, psm);
2459
0
        } else {
2460
0
            psm_item = proto_tree_add_uint(btl2cap_tree, hf_btl2cap_psm_dynamic, tvb, offset, 0, psm);
2461
0
            if (uuid.bt_uuid)
2462
0
                proto_item_append_text(psm_item, ": %s",
2463
0
                    val_to_str_ext_const(uuid.bt_uuid, &bluetooth_uuid_vals_ext, "Unknown service"));
2464
0
        }
2465
0
        proto_item_set_generated(psm_item);
2466
0
    }/*psm*/
2467
2468
0
    if (btl2cap_frame_data->first_fragment) {
2469
0
        proto_tree_add_item(btl2cap_tree, hf_btl2cap_le_sdu_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2470
0
        offset += 2;
2471
0
        length = length - 2;
2472
0
    }
2473
0
    pinfo->fragmented = true;
2474
0
    frag_btl2cap_le_sdu = fragment_add_seq_next(&btl2cap_le_sdu_reassembly_table,
2475
0
        tvb, offset,
2476
0
        pinfo,
2477
0
        cid,                                  /* uint32_t ID for fragments belonging together */
2478
0
        NULL,                                 /* data* */
2479
0
        length,                               /* Fragment length */
2480
0
        btl2cap_frame_data->more_fragments);  /* More fragments */
2481
2482
0
    new_tvb = process_reassembled_data(tvb, offset, pinfo,
2483
0
        "Reassembled SDU",
2484
0
        frag_btl2cap_le_sdu,
2485
0
        &btl2cap_le_sdu_frag_items,
2486
0
        NULL,
2487
0
        btl2cap_tree);
2488
2489
0
    if (new_tvb) {
2490
0
        if (psm) {
2491
0
            if (!dissector_try_uint_with_data(l2cap_cid_dissector_table, (uint32_t)cid, new_tvb, pinfo, tree, true, l2cap_data)) {
2492
0
                if (!dissector_try_uint_with_data(l2cap_psm_dissector_table, (uint32_t)psm, new_tvb, pinfo, tree, true, l2cap_data)) {
2493
                    /* not a known fixed PSM, try to find a registered service to a dynamic PSM */
2494
0
                    if (!dissector_try_string_with_data(bluetooth_uuid_table, print_numeric_bluetooth_uuid(pinfo->pool, &uuid), new_tvb, pinfo, tree, true, l2cap_data)) {
2495
                        /* unknown protocol. declare as data */
2496
0
                        proto_tree_add_item(btl2cap_tree, hf_btl2cap_payload, tvb, offset, length, ENC_NA);
2497
0
                    }
2498
0
                }
2499
0
            }
2500
0
        } else {
2501
            /* call next dissector */
2502
0
            if (!dissector_try_uint_with_data(l2cap_cid_dissector_table, (uint32_t)cid, new_tvb, pinfo, tree, true, l2cap_data)) {
2503
0
                proto_tree_add_item(btl2cap_tree, hf_btl2cap_payload, tvb, offset, length, ENC_NA);
2504
0
            }
2505
0
        }
2506
0
        return tvb_captured_length(tvb);
2507
0
    }
2508
2509
0
    col_set_str(pinfo->cinfo, COL_INFO, "L2CAP LE Fragment");
2510
0
    proto_tree_add_item(btl2cap_tree, hf_btl2cap_payload, tvb, offset, length, ENC_NA);
2511
2512
0
    return tvb_captured_length(tvb);
2513
0
}
2514
2515
static int
2516
dissect_i_frame_control_field(tvbuff_t *tvb, packet_info *pinfo, proto_tree *btl2cap_tree,
2517
        int offset, config_data_t *config_data, uint16_t *segment)
2518
0
{
2519
0
    uint32_t          control;
2520
0
    uint16_t          seg;
2521
0
    enum l2cap_ctl_field_format ctl_format = L2CAP_IFRAME_CONTROL_FIELD_STANDARD;
2522
2523
0
    if (config_data->mode == L2CAP_ENHANCED_RETRANSMISSION_MODE) {
2524
0
        ctl_format = L2CAP_IFRAME_CONTROL_FIELD_ENHANCED;
2525
0
    } else if (config_data->mode == L2CAP_STREAMING_MODE) {
2526
0
        ctl_format = L2CAP_IFRAME_CONTROL_FIELD_ENHANCED;
2527
0
        if (config_data->maxwindowsize == 0) {
2528
0
            ctl_format = L2CAP_IFRAME_CONTROL_FIELD_EXTENDED;
2529
0
        }
2530
0
    }
2531
2532
0
    if (ctl_format == L2CAP_IFRAME_CONTROL_FIELD_EXTENDED) {
2533
0
        control = tvb_get_letohl(tvb, offset);
2534
0
        seg = (control & 0x00030000) >> 16;
2535
0
    } else {
2536
0
        control = tvb_get_letohs(tvb, offset);
2537
0
        seg = (control & 0xC000) >> 14;
2538
0
    }
2539
0
    if (segment) {
2540
0
        *segment = seg;
2541
0
    }
2542
0
    switch (seg) {
2543
0
    case 0:
2544
0
        col_append_str(pinfo->cinfo, COL_INFO, "[I] Unsegmented SDU");
2545
0
        break;
2546
0
    case 1:
2547
0
        col_append_str(pinfo->cinfo, COL_INFO, "[I] Start SDU");
2548
0
        break;
2549
0
    case 2:
2550
0
        col_append_str(pinfo->cinfo, COL_INFO, "[I] End SDU");
2551
0
        break;
2552
0
    case 3:
2553
0
        col_append_str(pinfo->cinfo, COL_INFO, "[I] Continuation SDU");
2554
0
        break;
2555
0
    }
2556
0
    if (ctl_format == L2CAP_IFRAME_CONTROL_FIELD_EXTENDED) {
2557
0
        static int * const fields[] = {
2558
0
            &hf_btl2cap_ext_control_txseq,
2559
0
            &hf_btl2cap_ext_control_sar,
2560
0
            &hf_btl2cap_ext_control_reqseq,
2561
0
            &hf_btl2cap_ext_control_final,
2562
0
            &hf_btl2cap_ext_control_type,
2563
0
            NULL
2564
0
        };
2565
0
        proto_tree_add_bitmask(btl2cap_tree, tvb, offset, hf_btl2cap_ext_control_field, ett_btl2cap_control, fields, ENC_LITTLE_ENDIAN);
2566
0
        offset += 4;
2567
0
    } else {
2568
0
        if (ctl_format == L2CAP_IFRAME_CONTROL_FIELD_ENHANCED) {
2569
0
            static int * const fields[] = {
2570
0
                &hf_btl2cap_control_sar,
2571
0
                &hf_btl2cap_control_reqseq,
2572
0
                &hf_btl2cap_control_final,
2573
0
                &hf_btl2cap_control_txseq,
2574
0
                &hf_btl2cap_control_type,
2575
0
                NULL
2576
0
            };
2577
0
            proto_tree_add_bitmask(btl2cap_tree, tvb, offset, hf_btl2cap_control_field, ett_btl2cap_control, fields, ENC_LITTLE_ENDIAN);
2578
0
        } else {
2579
0
            static int * const fields[] = {
2580
0
                &hf_btl2cap_control_sar,
2581
0
                &hf_btl2cap_control_reqseq,
2582
0
                &hf_btl2cap_control_retransmissiondisable,
2583
0
                &hf_btl2cap_control_txseq,
2584
0
                &hf_btl2cap_control_type,
2585
0
                NULL
2586
0
            };
2587
0
            proto_tree_add_bitmask(btl2cap_tree, tvb, offset, hf_btl2cap_control_field, ett_btl2cap_control, fields, ENC_LITTLE_ENDIAN);
2588
0
        }
2589
0
        offset += 2;
2590
0
    }
2591
0
    return offset;
2592
0
}
2593
2594
static int
2595
dissect_i_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2596
        proto_tree *btl2cap_tree, psm_data_t *psm_data, uint16_t length,
2597
        int offset, config_data_t *config_data, btl2cap_data_t *l2cap_data)
2598
0
{
2599
0
    tvbuff_t         *next_tvb = NULL;
2600
0
    uint16_t          segment;
2601
0
    uint16_t          sdulen;
2602
0
    sdu_reassembly_t *mfp      = NULL;
2603
0
    uint16_t          psm      = (psm_data ? psm_data->psm : 0);
2604
2605
0
    offset = dissect_i_frame_control_field(tvb, pinfo, btl2cap_tree, offset, config_data, &segment);
2606
2607
    /*Segmented frames with SAR = start have an extra SDU length header field*/
2608
0
    if (segment == 0x01) {
2609
0
        proto_item *pi;
2610
2611
0
        sdulen = tvb_get_letohs(tvb, offset);
2612
0
        pi = proto_tree_add_item(btl2cap_tree, hf_btl2cap_sdulength, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2613
0
        offset += 2;
2614
2615
2616
        /* Detect malformed data */
2617
2618
0
        if (length <= 6) {
2619
0
            expert_add_info_format(pinfo, pi, &ei_btl2cap_sdulength_bad,
2620
0
                    "SDU length too short: %u", length);
2621
0
            THROW(ReportedBoundsError);
2622
0
        }
2623
2624
0
        length -= 6; /*Control, SDUlength, FCS*/
2625
2626
0
        if (sdulen < length) {
2627
0
            sdulen = length;
2628
0
            expert_add_info_format(pinfo, pi, &ei_btl2cap_sdulength_bad,
2629
0
                    "SDU length less than length of first packet (%u < %u)", sdulen, length);
2630
0
        }
2631
2632
0
        if (!pinfo->fd->visited) {
2633
0
            mfp              = wmem_new(wmem_file_scope(), sdu_reassembly_t);
2634
0
            mfp->first_frame = pinfo->num;
2635
0
            mfp->last_frame  = 0;
2636
0
            mfp->tot_len     = sdulen;
2637
0
            mfp->reassembled = (uint8_t *) wmem_alloc(wmem_file_scope(), sdulen);
2638
0
            tvb_memcpy(tvb, mfp->reassembled, offset, length);
2639
0
            mfp->cur_off     = length;
2640
0
            wmem_tree_insert32(config_data->start_fragments, pinfo->num, mfp);
2641
0
        } else {
2642
0
            mfp              = (sdu_reassembly_t *)wmem_tree_lookup32(config_data->start_fragments, pinfo->num);
2643
0
        }
2644
0
        if (mfp != NULL && mfp->last_frame) {
2645
0
            proto_item *item;
2646
0
            item = proto_tree_add_uint(btl2cap_tree, hf_btl2cap_reassembled_in, tvb, 0, 0, mfp->last_frame);
2647
0
            proto_item_set_generated(item);
2648
0
            col_append_frame_number(pinfo, COL_INFO, "[Reassembled in #%u] ", mfp->last_frame);
2649
0
        }
2650
0
    } else {
2651
0
        if (length <= 4) {
2652
0
            expert_add_info_format(pinfo, btl2cap_tree, &ei_btl2cap_length_bad,
2653
0
                    "Control / FCS length too short: %u", length);
2654
0
            THROW(ReportedBoundsError);
2655
0
        }
2656
0
        length -= 4; /*Control, FCS*/
2657
0
    }
2658
0
    if (segment == 0x02 || segment == 0x03) {
2659
0
        mfp = (sdu_reassembly_t *)wmem_tree_lookup32_le(config_data->start_fragments, pinfo->num);
2660
0
        if (!pinfo->fd->visited) {
2661
0
            if (mfp != NULL && !mfp->last_frame && (mfp->tot_len>=mfp->cur_off + length)) {
2662
0
                tvb_memcpy(tvb, mfp->reassembled + mfp->cur_off, offset, length);
2663
0
                mfp->cur_off += length;
2664
0
                if (segment == 0x02) {
2665
0
                    mfp->last_frame = pinfo->num;
2666
0
                }
2667
0
            }
2668
0
        }
2669
0
        if (mfp) {
2670
0
            proto_item *item;
2671
0
            item = proto_tree_add_uint(btl2cap_tree, hf_btl2cap_continuation_to, tvb, 0, 0, mfp->first_frame);
2672
0
            proto_item_set_generated(item);
2673
0
            col_append_fstr(pinfo->cinfo, COL_INFO, "[Continuation to #%u] ", mfp->first_frame);
2674
0
        }
2675
0
    }
2676
0
    if (segment == 0x02 && mfp != NULL && mfp->last_frame == pinfo->num && mfp->cur_off == mfp->tot_len) {
2677
        /* if mfp->cur_off != mfp->tot_len, there is missing data
2678
         * or other reassembly issues. */
2679
0
        next_tvb = tvb_new_child_real_data(tvb, (uint8_t *)mfp->reassembled, mfp->tot_len, mfp->tot_len);
2680
0
        add_new_data_source(pinfo, next_tvb, "Reassembled L2CAP");
2681
0
    }
2682
    /*pass up to higher layer if we have a complete packet*/
2683
0
    if (segment == 0x00) {
2684
0
        next_tvb = tvb_new_subset_length(tvb, offset, length);
2685
0
    }
2686
0
    if (next_tvb) {
2687
0
        if (psm) {
2688
0
            proto_item        *psm_item;
2689
0
            uint16_t           bt_uuid;
2690
0
             bluetooth_uuid_t  uuid;
2691
2692
0
            if (p_get_proto_data(pinfo->pool, pinfo, proto_btl2cap, PROTO_DATA_BTL2CAP_PSM ) == NULL) {
2693
0
                uint16_t *value_data;
2694
2695
0
                value_data = wmem_new(wmem_file_scope(), uint16_t);
2696
0
                *value_data = psm;
2697
2698
0
                p_add_proto_data(pinfo->pool, pinfo, proto_btl2cap, PROTO_DATA_BTL2CAP_PSM, value_data);
2699
0
            }
2700
2701
0
            bt_uuid = get_service_uuid(pinfo, l2cap_data, psm, psm_data->local_service);
2702
2703
0
            uuid.size = 2;
2704
0
            uuid.bt_uuid = bt_uuid;
2705
0
            uuid.data[0] = bt_uuid >> 8;
2706
0
            uuid.data[1] = bt_uuid & 0xFF;
2707
2708
0
            if (bt_uuid && p_get_proto_data(pinfo->pool, pinfo, proto_btl2cap, PROTO_DATA_BLUETOOTH_SERVICE_UUID) == NULL) {
2709
0
                char *value_data;
2710
2711
0
                value_data = wmem_strdup(wmem_file_scope(), print_numeric_bluetooth_uuid(pinfo->pool, &uuid));
2712
2713
0
                p_add_proto_data(pinfo->pool, pinfo, proto_btl2cap, PROTO_DATA_BLUETOOTH_SERVICE_UUID, value_data);
2714
0
            }
2715
2716
0
            if (psm < BTL2CAP_DYNAMIC_PSM_START) {
2717
0
                psm_item = proto_tree_add_uint(btl2cap_tree, hf_btl2cap_psm, tvb, offset, 0, psm);
2718
0
            } else {
2719
0
                psm_item = proto_tree_add_uint(btl2cap_tree, hf_btl2cap_psm_dynamic, tvb, offset, 0, psm);
2720
0
                if (uuid.bt_uuid)
2721
0
                    proto_item_append_text(psm_item, " (%s)",
2722
0
                                           val_to_str_ext_const(uuid.bt_uuid, &bluetooth_uuid_vals_ext, "Unknown service"));
2723
0
            }
2724
0
            proto_item_set_generated(psm_item);
2725
2726
            /* call next dissector */
2727
0
            if (!dissector_try_uint_with_data(l2cap_psm_dissector_table, (uint32_t) psm, next_tvb, pinfo, tree, true, l2cap_data)) {
2728
                /* not a known fixed PSM, try to find a registered service to a dynamic PSM */
2729
0
                if (!dissector_try_string_with_data(bluetooth_uuid_table, print_numeric_bluetooth_uuid(pinfo->pool, &uuid), next_tvb, pinfo, tree, true,l2cap_data)) {
2730
                    /* unknown protocol. declare as data */
2731
0
                    proto_tree_add_item(btl2cap_tree, hf_btl2cap_payload, next_tvb, 0, tvb_reported_length(next_tvb), ENC_NA);
2732
0
                }
2733
0
            }
2734
0
        }
2735
0
        else {
2736
0
            proto_tree_add_item(btl2cap_tree, hf_btl2cap_payload, next_tvb, 0, tvb_reported_length(next_tvb), ENC_NA);
2737
0
        }
2738
0
    }
2739
0
    offset += length;
2740
0
    proto_tree_add_checksum(btl2cap_tree, tvb, offset, hf_btl2cap_fcs,
2741
0
        hf_btl2cap_fcs_status, &ei_btl2cap_fcs_bad, pinfo,
2742
0
        crc16_plain_tvb_offset(tvb, 0, offset), ENC_LITTLE_ENDIAN,
2743
0
        PROTO_CHECKSUM_VERIFY);
2744
0
    offset +=  2;
2745
0
    return offset;
2746
0
}
2747
2748
static int
2749
dissect_s_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, proto_tree *btl2cap_tree,
2750
                uint16_t psm _U_, uint16_t length _U_, int offset, config_data_t *config_data _U_)
2751
2
{
2752
2
    uint32_t    control;
2753
2
    uint8_t supervisory;
2754
2
    enum l2cap_ctl_field_format ctl_format = L2CAP_IFRAME_CONTROL_FIELD_STANDARD;
2755
2756
2
    if (config_data) {
2757
0
        if (config_data->mode == L2CAP_ENHANCED_RETRANSMISSION_MODE) {
2758
0
            ctl_format = L2CAP_IFRAME_CONTROL_FIELD_ENHANCED;
2759
0
        } else if (config_data->mode == L2CAP_STREAMING_MODE) {
2760
0
            ctl_format = L2CAP_IFRAME_CONTROL_FIELD_ENHANCED;
2761
0
            if (config_data->maxwindowsize == 0) {
2762
0
                ctl_format = L2CAP_IFRAME_CONTROL_FIELD_EXTENDED;
2763
0
            }
2764
0
        }
2765
0
    }
2766
2767
2
    if (ctl_format == L2CAP_IFRAME_CONTROL_FIELD_EXTENDED) {
2768
0
        control = tvb_get_letohl(tvb, offset);
2769
0
        supervisory = (control & 0x000030000) >> 16;
2770
2
    } else {
2771
2
        control = tvb_get_letohs(tvb, offset);
2772
2
        supervisory = (control & 0x000C) >> 2;
2773
2
    }
2774
2
    switch (supervisory) {
2775
0
    case 0:
2776
0
        col_append_str(pinfo->cinfo, COL_INFO, "[S] Receiver Ready");
2777
0
        break;
2778
0
    case 1:
2779
0
        col_append_str(pinfo->cinfo, COL_INFO, "[S] Reject");
2780
0
        break;
2781
2
    default:
2782
2
        col_append_str(pinfo->cinfo, COL_INFO, "[S] Unknown supervisory frame");
2783
2
        break;
2784
2
    }
2785
2786
2
    if (ctl_format == L2CAP_IFRAME_CONTROL_FIELD_EXTENDED) {
2787
0
        static int * const fields[] = {
2788
0
            &hf_btl2cap_ext_control_poll,
2789
0
            &hf_btl2cap_ext_control_supervisory,
2790
0
            &hf_btl2cap_ext_control_reqseq,
2791
0
            &hf_btl2cap_ext_control_final,
2792
0
            &hf_btl2cap_ext_control_type,
2793
0
            NULL
2794
0
        };
2795
0
        proto_tree_add_bitmask(btl2cap_tree, tvb, offset, hf_btl2cap_ext_control_field, ett_btl2cap_control, fields, ENC_LITTLE_ENDIAN);
2796
0
        offset += 4;
2797
2
    } else {
2798
2
        if (ctl_format == L2CAP_IFRAME_CONTROL_FIELD_ENHANCED) {
2799
0
            static int * const fields[] = {
2800
0
                &hf_btl2cap_control_reqseq,
2801
0
                &hf_btl2cap_control_final,
2802
0
                &hf_btl2cap_control_poll,
2803
0
                &hf_btl2cap_control_supervisory,
2804
0
                &hf_btl2cap_control_type,
2805
0
                NULL
2806
0
            };
2807
0
            proto_tree_add_bitmask(btl2cap_tree, tvb, offset, hf_btl2cap_control_field, ett_btl2cap_control, fields, ENC_LITTLE_ENDIAN);
2808
2
        } else {
2809
2
            static int * const fields[] = {
2810
2
                &hf_btl2cap_control_reqseq,
2811
2
                &hf_btl2cap_control_retransmissiondisable,
2812
2
                &hf_btl2cap_control_supervisory,
2813
2
                &hf_btl2cap_control_type,
2814
2
                NULL
2815
2
            };
2816
2
            proto_tree_add_bitmask(btl2cap_tree, tvb, offset, hf_btl2cap_control_field, ett_btl2cap_control, fields, ENC_LITTLE_ENDIAN);
2817
2
        }
2818
2
        offset += 2;
2819
2
    }
2820
2821
2
    proto_tree_add_checksum(btl2cap_tree, tvb, offset, hf_btl2cap_fcs,
2822
2
        hf_btl2cap_fcs_status, &ei_btl2cap_fcs_bad, pinfo,
2823
2
        crc16_plain_tvb_offset(tvb, 0, offset), ENC_LITTLE_ENDIAN,
2824
2
        PROTO_CHECKSUM_VERIFY);
2825
2
    offset += 2;
2826
2
    return offset;
2827
2
}
2828
2829
static int
2830
dissect_btl2cap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
2831
2.26k
{
2832
2.26k
    int               offset       = 0;
2833
2.26k
    proto_item       *ti;
2834
2.26k
    proto_tree       *btl2cap_tree;
2835
2.26k
    proto_item       *length_item;
2836
2.26k
    uint16_t          length;
2837
2.26k
    uint16_t          cid;
2838
2.26k
    uint16_t          psm;
2839
2.26k
    uint16_t          control;
2840
2.26k
    tvbuff_t         *next_tvb     = NULL;
2841
2.26k
    psm_data_t       *psm_data;
2842
2.26k
    bthci_acl_data_t *acl_data;
2843
2.26k
    btl2cap_data_t   *l2cap_data;
2844
2.26k
    bool              dir_in_col = true;
2845
2846
2.26k
    acl_data = (bthci_acl_data_t *) data;
2847
2848
2.26k
    if ((acl_data) && (acl_data->is_btle)) {
2849
1
        dir_in_col = false;
2850
1
    }
2851
2.26k
    ti = proto_tree_add_item(tree, proto_btl2cap, tvb, offset, -1, ENC_NA);
2852
2.26k
    btl2cap_tree = proto_item_add_subtree(ti, ett_btl2cap);
2853
2854
2.26k
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "L2CAP");
2855
2856
2.26k
    if (dir_in_col) {
2857
2.26k
        switch (pinfo->p2p_dir) {
2858
16
        case P2P_DIR_SENT:
2859
16
            col_set_str(pinfo->cinfo, COL_INFO, "Sent ");
2860
16
            break;
2861
5
        case P2P_DIR_RECV:
2862
5
            col_set_str(pinfo->cinfo, COL_INFO, "Rcvd ");
2863
5
            break;
2864
2.24k
        default:
2865
2.24k
            col_set_str(pinfo->cinfo, COL_INFO, "UnknownDirection ");
2866
2.24k
            break;
2867
2.26k
        }
2868
2.26k
    } else {
2869
1
        col_clear(pinfo->cinfo, COL_INFO);
2870
1
    }
2871
2872
2.26k
    length  = tvb_get_letohs(tvb, offset);
2873
2.26k
    length_item = proto_tree_add_item(btl2cap_tree, hf_btl2cap_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2874
    /* Note this is captured length - some code later around fragments,
2875
     * FCS would have to be changed if this were reported length. */
2876
2.26k
    if (tvb_captured_length_remaining(tvb, offset + 4) < length) {
2877
2.24k
        expert_add_info(pinfo, length_item, &ei_btl2cap_length_bad);
2878
        /* Try to dissect as much as possible */
2879
2.24k
        length = tvb_captured_length_remaining(tvb, offset + 4);
2880
2.24k
    }
2881
2882
2.26k
    offset += 2;
2883
2884
2.26k
    cid = tvb_get_letohs(tvb, offset);
2885
2.26k
    proto_tree_add_item(btl2cap_tree, hf_btl2cap_cid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2886
2.26k
    if (p_get_proto_data(pinfo->pool, pinfo, proto_btl2cap, PROTO_DATA_BTL2CAP_CID ) == NULL) {
2887
1.82k
        uint16_t *value_data;
2888
2889
1.82k
        value_data = wmem_new(wmem_file_scope(), uint16_t);
2890
1.82k
        *value_data = cid;
2891
2892
1.82k
        p_add_proto_data(pinfo->pool, pinfo, proto_btl2cap, PROTO_DATA_BTL2CAP_CID, value_data);
2893
1.82k
    }
2894
2.26k
    offset += 2;
2895
2896
2.26k
    l2cap_data = wmem_new(pinfo->pool, btl2cap_data_t);
2897
2898
2.26k
    if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID)
2899
0
        l2cap_data->interface_id = pinfo->rec->rec_header.packet_header.interface_id;
2900
2.26k
    else
2901
2.26k
        l2cap_data->interface_id = HCI_INTERFACE_DEFAULT;
2902
2.26k
    if (acl_data) {
2903
3
        l2cap_data->adapter_id                  = acl_data->adapter_id;
2904
3
        l2cap_data->adapter_disconnect_in_frame = acl_data->adapter_disconnect_in_frame;
2905
3
        l2cap_data->chandle                     = acl_data->chandle;
2906
3
        l2cap_data->hci_disconnect_in_frame     = acl_data->disconnect_in_frame;
2907
3
        l2cap_data->remote_bd_addr_oui          = acl_data->remote_bd_addr_oui;
2908
3
        l2cap_data->remote_bd_addr_id           = acl_data->remote_bd_addr_id;
2909
2.25k
    } else {
2910
2.25k
        l2cap_data->adapter_id                  = HCI_ADAPTER_DEFAULT;
2911
2.25k
        l2cap_data->adapter_disconnect_in_frame = &bluetooth_max_disconnect_in_frame;
2912
2.25k
        l2cap_data->chandle                     = 0;
2913
2.25k
        l2cap_data->hci_disconnect_in_frame     = &bluetooth_max_disconnect_in_frame;
2914
2.25k
        l2cap_data->remote_bd_addr_oui          = 0;
2915
2.25k
        l2cap_data->remote_bd_addr_id           = 0;
2916
2.25k
    }
2917
2918
2.26k
    l2cap_data->disconnect_in_frame         = &bluetooth_max_disconnect_in_frame;
2919
2920
2.26k
    l2cap_data->cid              = cid;
2921
2.26k
    l2cap_data->local_cid        = BTL2CAP_UNKNOWN_CID;
2922
2.26k
    l2cap_data->remote_cid       = BTL2CAP_UNKNOWN_CID;
2923
2.26k
    l2cap_data->is_local_psm     = false;
2924
2.26k
    l2cap_data->psm              = 0;
2925
2926
2.26k
    if (cid == BTL2CAP_FIXED_CID_SIGNAL || cid == BTL2CAP_FIXED_CID_LE_SIGNAL) {
2927
        /* This is a command packet*/
2928
2.00k
        while (offset < length + 4) {
2929
2930
1.89k
            proto_item  *ti_command;
2931
1.89k
            proto_tree  *btl2cap_cmd_tree;
2932
1.89k
            uint8_t      cmd_code;
2933
1.89k
            uint8_t      cmd_ident;
2934
1.89k
            uint16_t     cmd_length;
2935
1.89k
            const char *cmd_str;
2936
2937
1.89k
            ti_command = proto_tree_add_none_format(btl2cap_tree,
2938
1.89k
                    hf_btl2cap_command, tvb,
2939
1.89k
                    offset, length,
2940
1.89k
                    "Command: ");
2941
1.89k
            btl2cap_cmd_tree = proto_item_add_subtree(ti_command, ett_btl2cap_cmd);
2942
2943
1.89k
            cmd_code = tvb_get_uint8(tvb, offset);
2944
1.89k
            proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_cmd_code,   tvb, offset, 1, ENC_LITTLE_ENDIAN);
2945
1.89k
            offset += 1;
2946
2947
1.89k
            cmd_ident = tvb_get_uint8(tvb, offset);
2948
1.89k
            proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_cmd_ident,  tvb, offset, 1, ENC_LITTLE_ENDIAN);
2949
1.89k
            offset += 1;
2950
2951
1.89k
            cmd_length = tvb_get_letohs(tvb, offset);
2952
1.89k
            proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_cmd_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2953
1.89k
            proto_item_set_len(ti_command, cmd_length + 4);
2954
1.89k
            offset += 2;
2955
2956
1.89k
            cmd_str = val_to_str_const(cmd_code, command_code_vals, "Unknown command");
2957
1.89k
            proto_item_append_text(ti_command, "%s", cmd_str);
2958
1.89k
            col_append_str(pinfo->cinfo, COL_INFO, cmd_str);
2959
2960
1.89k
            switch (cmd_code) {
2961
175
            case 0x01: /* Command Reject */
2962
175
                offset  = dissect_comrej(tvb, offset, pinfo, btl2cap_cmd_tree);
2963
175
                break;
2964
2965
113
            case 0x02: /* Connection Request */
2966
113
                offset  = dissect_connrequest(tvb, offset, pinfo, btl2cap_tree, btl2cap_cmd_tree, false, acl_data, l2cap_data);
2967
113
                break;
2968
2969
25
            case 0x03: /* Connection Response */
2970
25
                offset  = dissect_connresponse(tvb, offset, pinfo, btl2cap_cmd_tree, acl_data);
2971
25
                break;
2972
2973
42
            case 0x04: /* Configure Request */
2974
42
                offset  = dissect_configrequest(tvb, offset, pinfo, btl2cap_cmd_tree, cmd_length, acl_data);
2975
42
                break;
2976
2977
34
            case 0x05: /* Configure Response */
2978
34
                offset  = dissect_configresponse(tvb, offset, pinfo, btl2cap_cmd_tree, cmd_length, acl_data);
2979
34
                break;
2980
2981
311
            case 0x06: /* Disconnect Request */
2982
311
                offset  = dissect_disconnrequestresponse(tvb, offset, pinfo, btl2cap_tree, btl2cap_cmd_tree, acl_data, l2cap_data, true);
2983
311
                break;
2984
2985
45
            case 0x07: /* Disconnect Response */
2986
45
                offset  = dissect_disconnrequestresponse(tvb, offset, pinfo, btl2cap_tree, btl2cap_cmd_tree, acl_data, l2cap_data, false);
2987
45
                break;
2988
2989
2
            case 0x08: /* Echo Request */
2990
2
                proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_data, tvb, offset, -1, ENC_NA);
2991
2
                offset = tvb_reported_length(tvb);
2992
2
                break;
2993
2994
1
            case 0x09: /* Echo Response */
2995
1
                proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_data, tvb, offset, -1, ENC_NA);
2996
1
                offset = tvb_reported_length(tvb);
2997
1
                break;
2998
2999
18
            case 0x0a: /* Information Request */
3000
18
                offset  = dissect_inforequest(tvb, offset, pinfo, btl2cap_cmd_tree);
3001
18
                break;
3002
3003
3
            case 0x0b: /* Information Response */
3004
3
                offset  = dissect_inforesponse(tvb, offset, pinfo, btl2cap_cmd_tree);
3005
3
                break;
3006
3007
3
            case 0x0c: /* Create Channel Request */
3008
3
                offset  = dissect_connrequest(tvb, offset, pinfo, btl2cap_tree, btl2cap_cmd_tree, true, acl_data, l2cap_data);
3009
3
                break;
3010
3011
14
            case 0x0d: /* Create Channel Response */
3012
14
                offset  = dissect_chanresponse(tvb, offset, pinfo, btl2cap_cmd_tree, acl_data);
3013
14
                break;
3014
3015
132
            case 0x0e: /* Move Channel Request */
3016
132
                offset  = dissect_movechanrequest(tvb, offset, pinfo, btl2cap_cmd_tree);
3017
132
                break;
3018
3019
30
            case 0x0f: /* Move Channel Response */
3020
30
                offset  = dissect_movechanresponse(tvb, offset, pinfo, btl2cap_cmd_tree);
3021
30
                break;
3022
3023
92
            case 0x10: /* Move Channel Confirmation */
3024
92
                offset  = dissect_movechanconfirmation(tvb, offset, pinfo, btl2cap_cmd_tree);
3025
92
                break;
3026
3027
164
            case 0x11: /* Move Channel Confirmation Response */
3028
164
                offset  = dissect_movechanconfirmationresponse(tvb, offset, pinfo, btl2cap_cmd_tree);
3029
164
                break;
3030
3031
30
            case 0x12: /* Connection Parameter Request */
3032
30
                offset  = dissect_connparamrequest(tvb, offset, pinfo, btl2cap_cmd_tree);
3033
30
                break;
3034
3035
29
            case 0x13: /* Connection Parameter Response */
3036
29
                offset  = dissect_connparamresponse(tvb, offset, pinfo, btl2cap_cmd_tree);
3037
29
                break;
3038
3039
289
            case 0x14: /* LE Credit Based Connection Request */
3040
289
                offset = dissect_le_credit_based_connrequest(tvb, offset, pinfo, btl2cap_tree, btl2cap_cmd_tree, cid, cmd_ident, acl_data, l2cap_data);
3041
3042
289
                col_append_fstr(pinfo->cinfo, COL_INFO, " (CID: %04x, Initial Credits: %u)",
3043
289
                                tvb_get_letohs(tvb, offset - 8), tvb_get_letohs(tvb, offset - 2));
3044
289
                break;
3045
3046
121
            case 0x15: /* LE Credit Based Connection Response */
3047
121
                offset = dissect_le_credit_based_connresponse(tvb, offset, pinfo, btl2cap_cmd_tree, cid, cmd_ident, acl_data);
3048
3049
121
                col_append_fstr(pinfo->cinfo, COL_INFO, " (CID: %04x, Initial Credits: %u)",
3050
121
                                tvb_get_letohs(tvb, offset - 10), tvb_get_letohs(tvb, offset - 4));
3051
121
                break;
3052
3053
23
            case 0x16: /* LE Flow Control Credit */
3054
23
                proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_scid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3055
23
                offset += 2;
3056
3057
23
                proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_credits, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3058
23
                offset += 2;
3059
3060
23
                col_append_fstr(pinfo->cinfo, COL_INFO, " (CID: %04x, Credits: %u)",
3061
23
                                tvb_get_letohs(tvb, offset - 4), tvb_get_letohs(tvb, offset - 2));
3062
23
                break;
3063
3064
42
            case 0x17: /* L2CAP Credit Based Connection Request */
3065
42
                offset = dissect_l2cap_credit_based_connrequest(tvb, offset, pinfo, btl2cap_tree, btl2cap_cmd_tree, cid, cmd_ident, cmd_length, acl_data, l2cap_data);
3066
42
                break;
3067
3068
41
            case 0x18: /* L2CAP Credit Based Connection Response */
3069
41
                offset = dissect_l2cap_credit_based_connresponse(tvb, offset, pinfo, btl2cap_cmd_tree, cid, cmd_ident, cmd_length, acl_data);
3070
41
                break;
3071
3072
103
            default:
3073
103
                proto_tree_add_expert(btl2cap_cmd_tree, pinfo, &ei_btl2cap_unknown_command_code, tvb, offset, -1);
3074
103
                offset += tvb_reported_length_remaining(tvb, offset);
3075
103
                break;
3076
1.89k
            }
3077
1.89k
        }
3078
272
    }
3079
1.99k
    else if (cid == BTL2CAP_FIXED_CID_CONNLESS) { /* Connectionless reception channel */
3080
347
        col_append_str(pinfo->cinfo, COL_INFO, "Connectionless reception channel");
3081
3082
347
        psm = tvb_get_letohs(tvb, offset);
3083
347
        if (pinfo->p2p_dir == P2P_DIR_RECV) {
3084
0
            l2cap_data->local_cid = cid;
3085
0
            l2cap_data->remote_cid = BTL2CAP_UNKNOWN_CID;
3086
347
        } else {
3087
347
            l2cap_data->local_cid = BTL2CAP_UNKNOWN_CID;
3088
347
            l2cap_data->remote_cid = cid;
3089
347
        }
3090
347
        l2cap_data->psm = psm;
3091
347
        l2cap_data->disconnect_in_frame = &bluetooth_max_disconnect_in_frame;
3092
3093
347
        if (p_get_proto_data(pinfo->pool, pinfo, proto_btl2cap, PROTO_DATA_BTL2CAP_PSM ) == NULL) {
3094
347
            uint16_t *value_data;
3095
3096
347
            value_data = wmem_new(wmem_file_scope(), uint16_t);
3097
347
            *value_data = psm;
3098
3099
347
            p_add_proto_data(pinfo->pool, pinfo, proto_btl2cap, PROTO_DATA_BTL2CAP_PSM, value_data);
3100
347
        }
3101
3102
347
        proto_tree_add_item(btl2cap_tree, hf_btl2cap_psm, tvb, offset, 2, ENC_LITTLE_ENDIAN);
3103
347
        offset += 2;
3104
3105
        /* 3.2 "For G-frames, the PDU length equals the payload size plus the
3106
         * number of octets in the PSM."
3107
         * Subtract the PSM length. (Yes, technically the PSM is "at least"
3108
         * two octets in length, Little Endian where only the MSB (== Last)
3109
         * has least significant bit 0, and that's used to detect the size.
3110
         * We only use 2 octets everywhere in this dissector, though.)
3111
         */
3112
347
        if (length < 2) {
3113
1
            expert_add_info_format(pinfo, length_item, &ei_btl2cap_length_bad,
3114
1
                    "PDU length too short: %u (should include PSM)", length);
3115
1
            THROW(ReportedBoundsError);
3116
1
        }
3117
347
        length -= 2;
3118
347
        next_tvb = tvb_new_subset_length(tvb, offset, length);
3119
3120
        /* call next dissector */
3121
347
        if (!dissector_try_uint_with_data(l2cap_psm_dissector_table, (uint32_t) psm, next_tvb, pinfo, tree, true, l2cap_data)) {
3122
            /* not a known fixed PSM, try to find a registered service to a dynamic PSM */
3123
2
            uint16_t bt_uuid;
3124
2
            bluetooth_uuid_t  uuid;
3125
3126
2
            bt_uuid = get_service_uuid(pinfo, l2cap_data, psm, (pinfo->p2p_dir == P2P_DIR_RECV) ? true : false );
3127
3128
2
            uuid.size = 2;
3129
2
            uuid.bt_uuid = bt_uuid;
3130
2
            uuid.data[0] = bt_uuid >> 8;
3131
2
            uuid.data[1] = bt_uuid & 0xFF;
3132
3133
2
            if (bt_uuid && p_get_proto_data(pinfo->pool, pinfo, proto_bluetooth, PROTO_DATA_BLUETOOTH_SERVICE_UUID ) == NULL) {
3134
0
                char* value_data;
3135
3136
0
                value_data = wmem_strdup(wmem_file_scope(), print_numeric_bluetooth_uuid(pinfo->pool, &uuid));
3137
3138
0
                p_add_proto_data(pinfo->pool, pinfo, proto_bluetooth, PROTO_DATA_BLUETOOTH_SERVICE_UUID, value_data);
3139
0
            }
3140
3141
2
            if (!dissector_try_string_with_data(bluetooth_uuid_table, print_numeric_bluetooth_uuid(pinfo->pool, &uuid), next_tvb, pinfo, tree, true, l2cap_data)) {
3142
                /* unknown protocol. declare as data */
3143
2
                proto_tree_add_item(btl2cap_tree, hf_btl2cap_payload, tvb, offset, length, ENC_NA);
3144
2
            }
3145
2
            offset = tvb_captured_length(tvb);
3146
2
        }
3147
347
    }
3148
1.64k
    else if (cid <= BTL2CAP_FIXED_CID_LAST) {
3149
1.58k
        if (cid == BTL2CAP_FIXED_CID_AMP_MAN) {
3150
14
            control = tvb_get_letohs(tvb, offset);
3151
14
            if (control & 0x1) {
3152
2
                offset = dissect_s_frame(tvb, pinfo, tree, btl2cap_tree, 0 /* unused */, length, offset, NULL /* unused */);
3153
12
            } else {
3154
12
                static int * const fields[] = {
3155
12
                    &hf_btl2cap_control_sar,
3156
12
                    &hf_btl2cap_control_reqseq,
3157
12
                    &hf_btl2cap_control_retransmissiondisable,
3158
12
                    &hf_btl2cap_control_txseq,
3159
12
                    &hf_btl2cap_control_type,
3160
12
                    NULL
3161
12
                };
3162
12
                if (length <= 4) {
3163
0
                    expert_add_info_format(pinfo, length_item, &ei_btl2cap_length_bad,
3164
0
                            "Control / FCS length too short: %u", length);
3165
0
                    THROW(ReportedBoundsError);
3166
0
                }
3167
12
                length -= 4; /*Control, FCS*/
3168
12
                proto_tree_add_bitmask(btl2cap_tree, tvb, offset, hf_btl2cap_control_field, ett_btl2cap_control, fields, ENC_LITTLE_ENDIAN);
3169
12
                offset += 2;
3170
12
                proto_tree_add_checksum(btl2cap_tree, tvb, offset + length, hf_btl2cap_fcs,
3171
12
                    hf_btl2cap_fcs_status, &ei_btl2cap_fcs_bad, pinfo,
3172
12
                    crc16_plain_tvb_offset(tvb, 0, offset), ENC_LITTLE_ENDIAN,
3173
12
                    PROTO_CHECKSUM_VERIFY);
3174
3175
12
                next_tvb = tvb_new_subset_length(tvb, offset, length);
3176
12
            }
3177
14
        }
3178
1.57k
        else {
3179
1.57k
            next_tvb = tvb_new_subset_length(tvb, offset, length);
3180
1.57k
        }
3181
        /* call next dissector */
3182
1.58k
        if (next_tvb && !dissector_try_uint_with_data(l2cap_cid_dissector_table, (uint32_t) cid,
3183
1.58k
                    next_tvb, pinfo, tree, true, l2cap_data)) {
3184
            /* unknown protocol. declare as data */
3185
16
            proto_tree_add_item(btl2cap_tree, hf_btl2cap_payload, tvb, offset, length, ENC_NA);
3186
16
        }
3187
1.58k
        offset = tvb_captured_length(tvb);
3188
1.58k
    }
3189
58
    else /* if (cid > BTL2CAP_FIXED_CID_LAST) */ { /* Connection oriented channel */
3190
58
        wmem_tree_key_t    key[6];
3191
58
        uint32_t           k_interface_id;
3192
58
        uint32_t           k_adapter_id;
3193
58
        uint32_t           k_chandle;
3194
58
        uint32_t           k_cid;
3195
58
        uint32_t           k_frame_number;
3196
58
        uint32_t           interface_id;
3197
58
        uint32_t           adapter_id;
3198
58
        uint32_t           chandle;
3199
58
        uint32_t           key_cid;
3200
3201
58
        if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID)
3202
0
            interface_id = pinfo->rec->rec_header.packet_header.interface_id;
3203
58
        else
3204
58
            interface_id = HCI_INTERFACE_DEFAULT;
3205
58
        adapter_id   = (acl_data) ? acl_data->adapter_id : HCI_ADAPTER_DEFAULT;
3206
58
        chandle      = (acl_data) ? acl_data->chandle : 0;
3207
58
        key_cid      = cid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x00000000 : 0x80000000);
3208
3209
58
        k_interface_id = interface_id;
3210
58
        k_adapter_id   = adapter_id;
3211
58
        k_chandle      = chandle;
3212
58
        k_cid          = key_cid;
3213
58
        k_frame_number = pinfo->num;
3214
3215
58
        key[0].length = 1;
3216
58
        key[0].key    = &k_interface_id;
3217
58
        key[1].length = 1;
3218
58
        key[1].key    = &k_adapter_id;
3219
58
        key[2].length = 1;
3220
58
        key[2].key    = &k_chandle;
3221
58
        key[3].length = 1;
3222
58
        key[3].key    = &k_cid;
3223
58
        key[4].length = 1;
3224
58
        key[4].key    = &k_frame_number;
3225
58
        key[5].length = 0;
3226
58
        key[5].key    = NULL;
3227
3228
58
        psm_data = (psm_data_t *)wmem_tree_lookup32_array_le(cid_to_psm_table, key);
3229
58
        if (psm_data &&
3230
55
            psm_data->interface_id == interface_id &&
3231
55
            psm_data->adapter_id == adapter_id &&
3232
55
            psm_data->chandle == chandle &&
3233
53
            (psm_data->local_cid == key_cid ||
3234
53
             psm_data->remote_cid == key_cid) &&
3235
0
            psm_data->disconnect_in_frame > pinfo->num)
3236
0
        {
3237
0
            config_data_t  *config_data;
3238
0
            proto_item     *sub_item;
3239
0
            uint32_t        bt_uuid;
3240
3241
0
            psm = psm_data->psm;
3242
0
            l2cap_data->local_cid = psm_data->local_cid;
3243
0
            l2cap_data->remote_cid = psm_data->remote_cid;
3244
0
            l2cap_data->psm = psm;
3245
0
            l2cap_data->is_local_psm = psm_data->local_service;
3246
0
            l2cap_data->disconnect_in_frame = &psm_data->disconnect_in_frame;
3247
3248
0
            if (pinfo->p2p_dir == P2P_DIR_RECV)
3249
0
                config_data = &(psm_data->in);
3250
0
            else
3251
0
                config_data = &(psm_data->out);
3252
3253
0
            if (psm_data->connect_in_frame > 0 && psm_data->connect_in_frame < UINT32_MAX) {
3254
0
                sub_item = proto_tree_add_uint(btl2cap_tree, hf_btl2cap_connect_in_frame, tvb, 0, 0, psm_data->connect_in_frame);
3255
0
                proto_item_set_generated(sub_item);
3256
0
            }
3257
3258
0
            if (psm_data->disconnect_in_frame > 0 && psm_data->disconnect_in_frame < UINT32_MAX) {
3259
0
                sub_item = proto_tree_add_uint(btl2cap_tree, hf_btl2cap_disconnect_in_frame, tvb, 0, 0, psm_data->disconnect_in_frame);
3260
0
                proto_item_set_generated(sub_item);
3261
0
            }
3262
3263
0
            bt_uuid = get_service_uuid(pinfo, l2cap_data, psm_data->psm, psm_data->local_service);
3264
0
            if (bt_uuid) {
3265
0
                sub_item = proto_tree_add_uint(btl2cap_tree, hf_btl2cap_service, tvb, 0, 0, bt_uuid);
3266
0
                proto_item_set_generated(sub_item);
3267
0
            }
3268
3269
0
            if (config_data->mode == L2CAP_BASIC_MODE) {
3270
0
                offset = dissect_b_frame(tvb, pinfo, tree, btl2cap_tree, cid, psm, psm_data->local_service, length, offset, l2cap_data);
3271
0
            } else if (config_data->mode == L2CAP_LE_CREDIT_BASED_FLOW_CONTROL_MODE) {
3272
0
                bool is_retransmit = false;
3273
0
                if (acl_data) {
3274
0
                    is_retransmit = acl_data->is_btle_retransmit;
3275
0
                }
3276
0
                offset = dissect_le_frame(tvb, pinfo, tree, btl2cap_tree, cid, psm, psm_data->local_service, length, offset, config_data, l2cap_data, is_retransmit);
3277
0
            } else {
3278
0
                control = tvb_get_letohs(tvb, offset);
3279
0
                if (control & 0x1) {
3280
0
                    offset = dissect_s_frame(tvb, pinfo, tree, btl2cap_tree, psm, length, offset, config_data);
3281
0
                } else {
3282
0
                    offset = dissect_i_frame(tvb, pinfo, tree, btl2cap_tree, psm_data, length, offset, config_data, l2cap_data);
3283
0
                }
3284
0
            }
3285
58
        } else {
3286
58
            psm = 0;
3287
58
            offset = dissect_b_frame(tvb, pinfo, tree, btl2cap_tree, cid, psm, false, length, offset, l2cap_data);
3288
58
        }
3289
58
    }
3290
3291
2.10k
    return offset;
3292
2.26k
}
3293
3294
/* Register the protocol with Wireshark */
3295
void
3296
proto_register_btl2cap(void)
3297
14
{
3298
14
    expert_module_t *expert_btl2cap;
3299
    /* Setup list of header fields  See Section 1.6.1 for details*/
3300
14
    static hf_register_info hf[] = {
3301
14
        { &hf_btl2cap_length,
3302
14
          { "Length",           "btl2cap.length",
3303
14
            FT_UINT16, BASE_DEC, NULL, 0x0,
3304
14
            "L2CAP Payload Length", HFILL }
3305
14
        },
3306
14
        { &hf_btl2cap_cid,
3307
14
          { "CID",           "btl2cap.cid",
3308
14
            FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(cid_rvals), 0x0,
3309
14
            "L2CAP Channel Identifier", HFILL }
3310
14
        },
3311
14
        { &hf_btl2cap_payload,
3312
14
          { "Payload",           "btl2cap.payload",
3313
14
            FT_BYTES, BASE_NONE, NULL, 0x0,
3314
14
            "L2CAP Payload", HFILL }
3315
14
        },
3316
14
        { &hf_btl2cap_command,
3317
14
          { "Command",           "btl2cap.command",
3318
14
            FT_NONE, BASE_NONE, NULL, 0x0,
3319
14
            "L2CAP Command", HFILL }
3320
14
        },
3321
14
        { &hf_btl2cap_cmd_code,
3322
14
          { "Command Code",           "btl2cap.cmd_code",
3323
14
            FT_UINT8, BASE_HEX, VALS(command_code_vals), 0x0,
3324
14
            "L2CAP Command Code", HFILL }
3325
14
        },
3326
14
        { &hf_btl2cap_cmd_ident,
3327
14
          { "Command Identifier",           "btl2cap.cmd_ident",
3328
14
            FT_UINT8, BASE_HEX, NULL, 0x0,
3329
14
            "L2CAP Command Identifier", HFILL }
3330
14
        },
3331
14
        { &hf_btl2cap_cmd_length,
3332
14
          { "Command Length",           "btl2cap.cmd_length",
3333
14
            FT_UINT16, BASE_DEC, NULL, 0x0,
3334
14
            "L2CAP Command Length", HFILL }
3335
14
        },
3336
14
        { &hf_btl2cap_cmd_data,
3337
14
          { "Command Data",           "btl2cap.cmd_data",
3338
14
            FT_NONE, BASE_NONE, NULL, 0x0,
3339
14
            "L2CAP Command Data", HFILL }
3340
14
        },
3341
14
        { &hf_btl2cap_psm,
3342
14
          { "PSM",           "btl2cap.psm",
3343
14
            FT_UINT16, BASE_HEX, VALS(psm_vals), 0x0,
3344
14
            "Protocol/Service Multiplexer", HFILL }
3345
14
        },
3346
14
        { &hf_btl2cap_psm_dynamic,
3347
14
          { "Dynamic PSM",           "btl2cap.psm",
3348
14
            FT_UINT16, BASE_HEX, NULL, 0x0,
3349
14
            "Dynamic Protocol/Service Multiplexer", HFILL }
3350
14
        },
3351
14
        { &hf_btl2cap_scid,
3352
14
          { "Source CID",           "btl2cap.scid",
3353
14
            FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(cid_rvals), 0x0,
3354
14
            "Source Channel Identifier", HFILL }
3355
14
        },
3356
14
        { &hf_btl2cap_dcid,
3357
14
          { "Destination CID",           "btl2cap.dcid",
3358
14
            FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(cid_rvals), 0x0,
3359
14
            "Destination Channel Identifier", HFILL }
3360
14
        },
3361
14
        { &hf_btl2cap_icid,
3362
14
          { "Initiator CID",           "btl2cap.icid",
3363
14
            FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(cid_rvals), 0x0,
3364
14
            "Initiator Channel Identifier", HFILL }
3365
14
        },
3366
14
        { &hf_btl2cap_controller,
3367
14
          { "Controller ID",           "btl2cap.ctrl_id",
3368
14
            FT_UINT8, BASE_DEC, VALS(ctrl_id_code_vals), 0x0,
3369
14
            NULL, HFILL }
3370
14
        },
3371
14
        { &hf_btl2cap_dcontroller,
3372
14
          { "Controller ID",           "btl2cap.dctrl_id",
3373
14
            FT_UINT8, BASE_DEC, VALS(ctrl_id_code_vals), 0x0,
3374
14
            "Destination Controller ID", HFILL }
3375
14
        },
3376
14
        { &hf_btl2cap_result,
3377
14
          { "Result",           "btl2cap.result",
3378
14
            FT_UINT16, BASE_HEX, VALS(result_vals), 0x0,
3379
14
            NULL, HFILL }
3380
14
        },
3381
14
        { &hf_btl2cap_move_result,
3382
14
          { "Move Result",           "btl2cap.move_result",
3383
14
            FT_UINT16, BASE_HEX, VALS(move_result_vals), 0x0,
3384
14
            NULL, HFILL }
3385
14
        },
3386
14
        { &hf_btl2cap_move_confirmation_result,
3387
14
          { "Move Result",           "btl2cap.move_result",
3388
14
            FT_UINT16, BASE_HEX, VALS(move_result_confirmation_vals), 0x0,
3389
14
            NULL, HFILL }
3390
14
        },
3391
14
        { &hf_btl2cap_status,
3392
14
          { "Status",           "btl2cap.status",
3393
14
            FT_UINT16, BASE_HEX, VALS(status_vals), 0x0,
3394
14
            NULL, HFILL }
3395
14
        },
3396
14
        { &hf_btl2cap_rej_reason,
3397
14
          { "Reason",           "btl2cap.rej_reason",
3398
14
            FT_UINT16, BASE_HEX, VALS(reason_vals), 0x0,
3399
14
            NULL, HFILL }
3400
14
        },
3401
14
        { &hf_btl2cap_sig_mtu,
3402
14
          { "Maximum Signalling MTU",           "btl2cap.sig_mtu",
3403
14
            FT_UINT16, BASE_DEC, NULL, 0x0,
3404
14
            NULL, HFILL }
3405
14
        },
3406
14
        { &hf_btl2cap_info_mtu,
3407
14
          { "Remote Entity MTU",           "btl2cap.info_mtu",
3408
14
            FT_UINT16, BASE_DEC, NULL, 0x0,
3409
14
            "Remote entity acceptable connectionless MTU", HFILL }
3410
14
        },
3411
14
        { &hf_btl2cap_info_flowcontrol,
3412
14
          { "Flow Control Mode",           "btl2cap.info_flowcontrol",
3413
14
            FT_UINT32, BASE_DEC, NULL, 0x01,
3414
14
            "Flow Control mode support", HFILL }
3415
14
        },
3416
14
        { &hf_btl2cap_info_retransmission,
3417
14
          { "Retransmission Mode",         "btl2cap.info_retransmission",
3418
14
            FT_UINT32, BASE_DEC, NULL, 0x02,
3419
14
            "Retransmission mode support", HFILL }
3420
14
        },
3421
14
        { &hf_btl2cap_info_bidirqos,
3422
14
          { "Bi-Directional QOS",          "btl2cap.info_bidirqos",
3423
14
            FT_UINT32, BASE_DEC, NULL, 0x04,
3424
14
            "Bi-Directional QOS support", HFILL }
3425
14
        },
3426
14
        { &hf_btl2cap_info_enh_retransmission,
3427
14
          { "Enhanced Retransmission Mode", "btl2cap.info_enh_retransmission",
3428
14
            FT_UINT32, BASE_DEC, NULL, 0x08,
3429
14
            "Enhanced Retransmission mode support", HFILL }
3430
14
        },
3431
14
        { &hf_btl2cap_info_streaming,
3432
14
          { "Streaming Mode", "btl2cap.info_streaming",
3433
14
            FT_UINT32, BASE_DEC, NULL, 0x10,
3434
14
            "Streaming mode support", HFILL }
3435
14
        },
3436
14
        { &hf_btl2cap_info_fcs,
3437
14
          { "FCS", "btl2cap.info_fcs",
3438
14
            FT_UINT32, BASE_DEC, NULL, 0x20,
3439
14
            "FCS support", HFILL }
3440
14
        },
3441
14
        { &hf_btl2cap_info_flow_spec,
3442
14
          { "Extended Flow Specification for BR/EDR", "btl2cap.info_flow_spec",
3443
14
            FT_UINT32, BASE_DEC, NULL, 0x40,
3444
14
            "Extended Flow Specification for BR/EDR support", HFILL }
3445
14
        },
3446
14
        { &hf_btl2cap_info_fixedchan,
3447
14
          { "Fixed Channels", "btl2cap.info_fixedchan",
3448
14
            FT_UINT32, BASE_DEC, NULL, 0x80,
3449
14
            "Fixed Channels support", HFILL }
3450
14
        },
3451
14
        { &hf_btl2cap_info_window,
3452
14
          { "Extended Window Size", "btl2cap.info_window",
3453
14
            FT_UINT32, BASE_DEC, NULL, 0x0100,
3454
14
            "Extended Window Size support", HFILL }
3455
14
        },
3456
14
        { &hf_btl2cap_info_unicast,
3457
14
          { "Unicast Connectionless Data Reception", "btl2cap.info_unicast",
3458
14
            FT_UINT32, BASE_DEC, NULL, 0x0200,
3459
14
            "Unicast Connectionless Data Reception support", HFILL }
3460
14
        },
3461
14
        { &hf_btl2cap_info_fixedchans,
3462
14
          { "Fixed Channels", "btl2cap.info_fixedchans",
3463
14
            FT_NONE, BASE_NONE, NULL, 0x0,
3464
14
            NULL, HFILL }
3465
14
        },
3466
14
        { &hf_btl2cap_info_fixedchans_null,
3467
14
          { "Null identifier", "btl2cap.info_fixedchans_null",
3468
14
            FT_UINT32, BASE_DEC, NULL, 0x1,
3469
14
            NULL, HFILL }
3470
14
        },
3471
14
        { &hf_btl2cap_info_fixedchans_signal,
3472
14
          { "L2CAP signaling channel", "btl2cap.info_fixedchans_signal",
3473
14
            FT_UINT32, BASE_DEC, NULL, 0x2,
3474
14
            NULL, HFILL }
3475
14
        },
3476
14
        { &hf_btl2cap_info_fixedchans_connless,
3477
14
          { "Connectionless reception", "btl2cap.info_fixedchans_connless",
3478
14
            FT_UINT32, BASE_DEC, NULL, 0x4,
3479
14
            NULL, HFILL }
3480
14
        },
3481
14
        { &hf_btl2cap_info_fixedchans_amp_man,
3482
14
          { "AMP Manager protocol", "btl2cap.info_fixedchans_amp_man",
3483
14
            FT_UINT32, BASE_DEC, NULL, 0x8,
3484
14
            NULL, HFILL }
3485
14
        },
3486
14
        { &hf_btl2cap_info_fixedchans_rfu,
3487
14
          { "Reserved for future use", "btl2cap.info_fixedchans_rfu",
3488
14
            FT_UINT32, BASE_DEC, NULL, 0x00000070,
3489
14
            NULL, HFILL }
3490
14
        },
3491
14
        { &hf_btl2cap_info_fixedchans_smp,
3492
14
          { "BR/EDR Security Manager", "btl2cap.info_fixedchans_smp",
3493
14
            FT_UINT32, BASE_DEC, NULL, 0x00000080,
3494
14
            NULL, HFILL }
3495
14
        },
3496
14
        { &hf_btl2cap_info_fixedchans_amp_test,
3497
14
          { "AMP Test Manager", "btl2cap.info_fixedchans_amp_test",
3498
14
            FT_UINT32, BASE_DEC, NULL, 0x80000000,
3499
14
            NULL, HFILL }
3500
14
        },
3501
14
        { &hf_btl2cap_info_type,
3502
14
          { "Information Type",           "btl2cap.info_type",
3503
14
            FT_UINT16, BASE_HEX, VALS(info_type_vals), 0x0,
3504
14
            "Type of implementation-specific information", HFILL }
3505
14
        },
3506
14
        { &hf_btl2cap_info_result,
3507
14
          { "Result",           "btl2cap.info_result",
3508
14
            FT_UINT16, BASE_HEX, VALS(info_result_vals), 0x0,
3509
14
            "Information about the success of the request", HFILL }
3510
14
        },
3511
14
        { &hf_btl2cap_info_extfeatures,
3512
14
          { "Extended Features",           "btl2cap.info_extfeatures",
3513
14
            FT_NONE, BASE_NONE, NULL, 0x0,
3514
14
            "Extended Features Mask", HFILL }
3515
14
        },
3516
14
        { &hf_btl2cap_flags_reserved,
3517
14
          { "Reserved",           "btl2cap.flags.reserved",
3518
14
            FT_UINT16, BASE_HEX, NULL, 0xFFFE,
3519
14
            NULL, HFILL }
3520
14
        },
3521
14
        { &hf_btl2cap_flags_continuation,
3522
14
          { "Continuation Flag",           "btl2cap.flags.continuation",
3523
14
            FT_BOOLEAN, 16, NULL, 0x0001,
3524
14
            NULL, HFILL }
3525
14
        },
3526
14
        { &hf_btl2cap_configuration_result,
3527
14
          { "Result",           "btl2cap.conf_result",
3528
14
            FT_UINT16, BASE_HEX, VALS(configuration_result_vals), 0x0,
3529
14
            "Configuration Result", HFILL }
3530
14
        },
3531
14
        { &hf_btl2cap_option_type,
3532
14
          { "Type",           "btl2cap.option_type",
3533
14
            FT_UINT8, BASE_HEX, VALS(option_type_vals), 0x0,
3534
14
            "Type of option", HFILL }
3535
14
        },
3536
14
        { &hf_btl2cap_option_length,
3537
14
          { "Length",           "btl2cap.option_length",
3538
14
            FT_UINT8, BASE_DEC, NULL, 0x0,
3539
14
            "Number of octets in option payload", HFILL }
3540
14
        },
3541
14
        { &hf_btl2cap_option_mtu,
3542
14
          { "MTU",           "btl2cap.option_mtu",
3543
14
            FT_UINT16, BASE_DEC, NULL, 0x0,
3544
14
            "Maximum Transmission Unit", HFILL }
3545
14
        },
3546
14
        { &hf_btl2cap_option_flushTO,
3547
14
          { "Flush Timeout (ms)",           "btl2cap.option_flushto",
3548
14
            FT_UINT16, BASE_DEC, NULL, 0x0,
3549
14
            "Flush Timeout in milliseconds", HFILL }
3550
14
        },
3551
14
        { &hf_btl2cap_option_flush_to_us,
3552
14
          { "Flush Timeout (us)",           "btl2cap.option_flushto",
3553
14
            FT_UINT32, BASE_DEC, NULL, 0x0,
3554
14
            "Flush Timeout (microseconds)", HFILL }
3555
14
        },
3556
14
        { &hf_btl2cap_option_sdu_size,
3557
14
          { "Maximum SDU Size",           "btl2cap.option_sdu_size",
3558
14
            FT_UINT16, BASE_DEC, NULL, 0x0,
3559
14
            NULL, HFILL }
3560
14
        },
3561
14
        { &hf_btl2cap_option_sdu_arrival_time,
3562
14
          { "SDU Inter-arrival Time (us)",           "btl2cap.option_sdu_arrival_time",
3563
14
            FT_UINT32, BASE_DEC, NULL, 0x0,
3564
14
            "SDU Inter-arrival Time (microseconds)", HFILL }
3565
14
        },
3566
14
        { &hf_btl2cap_option_identifier,
3567
14
          { "Identifier",           "btl2cap.option_ident",
3568
14
            FT_UINT8, BASE_HEX, NULL, 0x0,
3569
14
            "Flow Specification Identifier", HFILL }
3570
14
        },
3571
14
        { &hf_btl2cap_option_access_latency,
3572
14
          { "Access Latency (us)",           "btl2cap.option_access_latency",
3573
14
            FT_UINT32, BASE_DEC, NULL, 0x0,
3574
14
            "Access Latency (microseconds)", HFILL }
3575
14
        },
3576
14
        { &hf_btl2cap_option_flags,
3577
14
          { "Flags",           "btl2cap.option_flags",
3578
14
            FT_UINT8, BASE_HEX, NULL, 0x0,
3579
14
            "Flags - must be set to 0 (Reserved for future use)", HFILL }
3580
14
        },
3581
14
        { &hf_btl2cap_option_service_type,
3582
14
          { "Service Type",           "btl2cap.option_servicetype",
3583
14
            FT_UINT8, BASE_HEX, VALS(option_servicetype_vals), 0x0,
3584
14
            "Level of service required", HFILL }
3585
14
        },
3586
14
        { &hf_btl2cap_option_tokenrate,
3587
14
          { "Token Rate (bytes/s)",           "btl2cap.option_tokenrate",
3588
14
            FT_UINT32, BASE_DEC, NULL, 0x0,
3589
14
            "Rate at which traffic credits are granted (bytes/s)", HFILL }
3590
14
        },
3591
14
        { &hf_btl2cap_option_tokenbucketsize,
3592
14
          { "Token Bucket Size (bytes)",           "btl2cap.option_tokenbsize",
3593
14
            FT_UINT32, BASE_DEC, NULL, 0x0,
3594
14
            "Size of the token bucket (bytes)", HFILL }
3595
14
        },
3596
14
        { &hf_btl2cap_option_peakbandwidth,
3597
14
          { "Peak Bandwidth (bytes/s)",           "btl2cap.option_peakbandwidth",
3598
14
            FT_UINT32, BASE_DEC, NULL, 0x0,
3599
14
            "Limit how fast packets may be sent (bytes/s)", HFILL }
3600
14
        },
3601
14
        { &hf_btl2cap_option_latency,
3602
14
          { "Latency (microseconds)",           "btl2cap.option_latency",
3603
14
            FT_UINT32, BASE_DEC, NULL, 0x0,
3604
14
            "Maximal acceptable delay (microseconds)", HFILL }
3605
14
        },
3606
14
        { &hf_btl2cap_option_delayvariation,
3607
14
          { "Delay Variation (microseconds)",           "btl2cap.option_delayvar",
3608
14
            FT_UINT32, BASE_DEC, NULL, 0x0,
3609
14
            "Difference between maximum and minimum delay (microseconds)", HFILL }
3610
14
        },
3611
14
        { &hf_btl2cap_option_retransmissionmode,
3612
14
          { "Mode",                               "btl2cap.retransmissionmode",
3613
14
            FT_UINT8, BASE_HEX, VALS(option_retransmissionmode_vals), 0x0,
3614
14
            "Retransmission/Flow Control mode", HFILL }
3615
14
        },
3616
14
        { &hf_btl2cap_option_txwindow,
3617
14
          { "TxWindow",                           "btl2cap.txwindow",
3618
14
            FT_UINT8, BASE_DEC, NULL, 0x0,
3619
14
            "Retransmission window size", HFILL }
3620
14
        },
3621
14
        { &hf_btl2cap_option_maxtransmit,
3622
14
          { "MaxTransmit",                        "btl2cap.maxtransmit",
3623
14
            FT_UINT8, BASE_DEC, NULL, 0x0,
3624
14
            "Maximum I-frame retransmissions", HFILL }
3625
14
        },
3626
14
        { &hf_btl2cap_option_retransmittimeout,
3627
14
          { "Retransmit timeout (ms)",            "btl2cap.retransmittimeout",
3628
14
            FT_UINT16, BASE_DEC, NULL, 0x0,
3629
14
            "Retransmission timeout (milliseconds)", HFILL }
3630
14
        },
3631
14
        { &hf_btl2cap_option_monitortimeout,
3632
14
          { "Monitor Timeout (ms)",               "btl2cap.monitortimeout",
3633
14
            FT_UINT16, BASE_DEC, NULL, 0x0,
3634
14
            "S-frame transmission interval (milliseconds)", HFILL }
3635
14
        },
3636
14
        { &hf_btl2cap_option_mps,
3637
14
          { "MPS",                                "btl2cap.mps",
3638
14
            FT_UINT16, BASE_DEC, NULL, 0x0,
3639
14
            "Maximum PDU Payload Size", HFILL }
3640
14
        },
3641
14
        { &hf_btl2cap_option_fcs,
3642
14
          { "FCS",           "btl2cap.option_fcs",
3643
14
            FT_UINT16, BASE_HEX, VALS(option_fcs_vals), 0x0,
3644
14
            "Frame Check Sequence", HFILL }
3645
14
        },
3646
14
        { &hf_btl2cap_option_window,
3647
14
          { "Extended Window Size",           "btl2cap.option_window",
3648
14
            FT_UINT16, BASE_DEC, NULL, 0x0,
3649
14
            NULL, HFILL }
3650
14
        },
3651
14
        { &hf_btl2cap_option,
3652
14
          { "Configuration Parameter Option",           "btl2cap.conf_param_option",
3653
14
            FT_NONE, BASE_NONE, NULL, 0x0,
3654
14
            NULL, HFILL }
3655
14
        },
3656
14
        { &hf_btl2cap_control_sar,
3657
14
          { "Segmentation and reassembly",           "btl2cap.control_sar",
3658
14
            FT_UINT16, BASE_HEX, VALS(control_sar_vals), 0xC000,
3659
14
            NULL, HFILL }
3660
14
        },
3661
14
        { &hf_btl2cap_ext_control_sar,
3662
14
          { "Segmentation and reassembly",           "btl2cap.control_sar",
3663
14
            FT_UINT32, BASE_HEX, VALS(control_sar_vals), 0x00030000,
3664
14
            NULL, HFILL }
3665
14
        },
3666
14
        { &hf_btl2cap_control_reqseq,
3667
14
          { "ReqSeq",           "btl2cap.control_reqseq",
3668
14
            FT_UINT16, BASE_DEC, NULL, 0x3F00,
3669
14
            "Request Sequence Number", HFILL }
3670
14
        },
3671
14
        { &hf_btl2cap_ext_control_reqseq,
3672
14
          { "ReqSeq",           "btl2cap.control_reqseq",
3673
14
            FT_UINT32, BASE_DEC, NULL, 0x0000FFFC,
3674
14
            "Request Sequence Number", HFILL }
3675
14
        },
3676
14
        { &hf_btl2cap_control_txseq,
3677
14
          { "TxSeq",           "btl2cap.control_txseq",
3678
14
            FT_UINT16, BASE_DEC, NULL, 0x007E,
3679
14
            "Transmitted Sequence Number", HFILL }
3680
14
        },
3681
14
        { &hf_btl2cap_ext_control_txseq,
3682
14
          { "TxSeq",           "btl2cap.control_txseq",
3683
14
            FT_UINT32, BASE_DEC, NULL, 0xFFFC0000,
3684
14
            "Transmitted Sequence Number", HFILL }
3685
14
        },
3686
14
        { &hf_btl2cap_control_retransmissiondisable,
3687
14
          { "R",           "btl2cap.control_retransmissiondisable",
3688
14
            FT_UINT16, BASE_HEX, NULL, 0x0080,
3689
14
            "Retransmission Disable", HFILL }
3690
14
        },
3691
14
        { &hf_btl2cap_control_poll,
3692
14
          { "P",           "btl2cap.control_poll",
3693
14
            FT_UINT16, BASE_HEX, NULL, 0x0010,
3694
14
            "P-bit", HFILL }
3695
14
        },
3696
14
        { &hf_btl2cap_ext_control_poll,
3697
14
          { "P",           "btl2cap.control_poll",
3698
14
            FT_UINT32, BASE_HEX, NULL, 0x00040000,
3699
14
            "P-bit", HFILL }
3700
14
        },
3701
14
        { &hf_btl2cap_control_final,
3702
14
          { "F",           "btl2cap.control_final",
3703
14
            FT_UINT16, BASE_HEX, NULL, 0x0080,
3704
14
            "F-bit", HFILL }
3705
14
        },
3706
14
        { &hf_btl2cap_ext_control_final,
3707
14
          { "F",           "btl2cap.control_final",
3708
14
            FT_UINT32, BASE_HEX, NULL, 0x00000002,
3709
14
            "F-bit", HFILL }
3710
14
        },
3711
14
        { &hf_btl2cap_control_supervisory,
3712
14
          { "S",           "btl2cap.control_supervisory",
3713
14
            FT_UINT16, BASE_HEX, VALS(control_supervisory_vals), 0x000C,
3714
14
            "Supervisory Function", HFILL }
3715
14
        },
3716
14
        { &hf_btl2cap_ext_control_supervisory,
3717
14
          { "S",           "btl2cap.control_supervisory",
3718
14
            FT_UINT32, BASE_HEX, VALS(control_supervisory_vals), 0x00030000,
3719
14
            "Supervisory Function", HFILL }
3720
14
        },
3721
14
        { &hf_btl2cap_control_type,
3722
14
          { "Frame Type",           "btl2cap.control_type",
3723
14
            FT_UINT16, BASE_HEX, VALS(control_type_vals), 0x0001,
3724
14
            NULL, HFILL }
3725
14
        },
3726
14
        { &hf_btl2cap_ext_control_type,
3727
14
          { "Frame Type",           "btl2cap.control_type",
3728
14
            FT_UINT32, BASE_HEX, VALS(control_type_vals), 0x00000001,
3729
14
            NULL, HFILL }
3730
14
        },
3731
14
        { &hf_btl2cap_control_field,
3732
14
          { "Control field",           "btl2cap.control",
3733
14
            FT_UINT16, BASE_HEX, NULL, 0x0,
3734
14
            NULL, HFILL }
3735
14
        },
3736
14
        { &hf_btl2cap_ext_control_field,
3737
14
          { "Control field",           "btl2cap.control",
3738
14
            FT_UINT32, BASE_HEX, NULL, 0x0,
3739
14
            NULL, HFILL }
3740
14
        },
3741
14
        { &hf_btl2cap_fcs,
3742
14
          { "FCS",           "btl2cap.fcs",
3743
14
            FT_UINT16, BASE_HEX, NULL, 0,
3744
14
            "Frame Check Sequence", HFILL }
3745
14
        },
3746
14
        { &hf_btl2cap_fcs_status,
3747
14
          { "FCS Status",    "btl2cap.fcs.status",
3748
14
            FT_UINT8, BASE_NONE, VALS(proto_checksum_vals), 0x0,
3749
14
            NULL, HFILL }
3750
14
        },
3751
14
        { &hf_btl2cap_sdulength,
3752
14
          { "SDU Length",           "btl2cap.sdulength",
3753
14
            FT_UINT16, BASE_DEC, NULL, 0,
3754
14
            NULL, HFILL }
3755
14
        },
3756
14
        { &hf_btl2cap_reassembled_in,
3757
14
          { "This SDU is reassembled in frame",           "btl2cap.reassembled_in",
3758
14
            FT_FRAMENUM, BASE_NONE, NULL, 0,
3759
14
            "This SDU is reassembled in frame #", HFILL }
3760
14
        },
3761
14
        { &hf_btl2cap_continuation_to,
3762
14
          { "This is a continuation to the SDU in frame",           "btl2cap.continuation_to",
3763
14
            FT_FRAMENUM, BASE_NONE, NULL, 0,
3764
14
            "This is a continuation to the SDU in frame #", HFILL }
3765
14
        },
3766
14
        { &hf_btl2cap_min_interval,
3767
14
          { "Min. Interval",           "btl2cap.min_interval",
3768
14
            FT_UINT16, BASE_DEC, NULL, 0,
3769
14
            NULL, HFILL }
3770
14
        },
3771
14
        { &hf_btl2cap_max_interval,
3772
14
          { "Max. Interval",           "btl2cap.max_interval",
3773
14
            FT_UINT16, BASE_DEC, NULL, 0,
3774
14
            NULL, HFILL }
3775
14
        },
3776
14
        { &hf_btl2cap_peripheral_latency,
3777
14
          { "Peripheral Latency",           "btl2cap.peripheral_latency",
3778
14
            FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_ll_connection_event), 0,
3779
14
            NULL, HFILL }
3780
14
        },
3781
14
        { &hf_btl2cap_timeout_multiplier,
3782
14
          { "Timeout Multiplier",           "btl2cap.timeout_multiplier",
3783
14
            FT_UINT16, BASE_DEC, NULL, 0,
3784
14
            NULL, HFILL }
3785
14
        },
3786
14
        { &hf_btl2cap_conn_param_result,
3787
14
          { "Move Result",           "btl2cap.move_result",
3788
14
            FT_UINT16, BASE_HEX, VALS(conn_param_result_vals), 0x0,
3789
14
            NULL, HFILL }
3790
14
        },
3791
14
        { &hf_btl2cap_le_result,
3792
14
          { "LE Result",           "btl2cap.le_result",
3793
14
            FT_UINT16, BASE_HEX, VALS(le_result_vals), 0x0,
3794
14
            NULL, HFILL }
3795
14
        },
3796
14
        { &hf_btl2cap_credits,
3797
14
          { "Credits",               "btl2cap.credits",
3798
14
            FT_UINT16, BASE_DEC, NULL, 0x0,
3799
14
            "L2CAP Channel Identifier", HFILL }
3800
14
        },
3801
14
        { &hf_btl2cap_initial_credits,
3802
14
          { "Initial Credits",       "btl2cap.initial_credits",
3803
14
            FT_UINT16, BASE_DEC, NULL, 0x0,
3804
14
            "L2CAP Channel Identifier", HFILL }
3805
14
        },
3806
14
        { &hf_btl2cap_le_psm,
3807
14
          { "LE PSM",           "btl2cap.le_psm",
3808
14
            FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(le_psm_rvals), 0x0,
3809
14
            "Protocol/Service Multiplexer", HFILL }
3810
14
        },
3811
14
        { &hf_btl2cap_data,
3812
14
          { "Data",           "btl2cap.data",
3813
14
            FT_BYTES, BASE_NONE, NULL, 0x0,
3814
14
            NULL, HFILL }
3815
14
        },
3816
14
        { &hf_btl2cap_service,
3817
14
          { "Service",           "btl2cap.service",
3818
14
            FT_UINT16, BASE_HEX | BASE_EXT_STRING, &bluetooth_uuid_vals_ext, 0x0,
3819
14
            NULL, HFILL }
3820
14
        },
3821
14
        { &hf_btl2cap_connect_in_frame,
3822
14
            { "Connect in frame",                            "btl2cap.connect_in",
3823
14
            FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3824
14
            NULL, HFILL }
3825
14
        },
3826
14
        { &hf_btl2cap_disconnect_in_frame,
3827
14
            { "Disconnect in frame",                         "btl2cap.disconnect_in",
3828
14
            FT_FRAMENUM, BASE_NONE, NULL, 0x0,
3829
14
            NULL, HFILL }
3830
14
        },
3831
14
        { &hf_btl2cap_le_sdu_fragments,
3832
14
        { "SDU fragments", "btl2cap.le_sdu.fragments",
3833
14
            FT_NONE, BASE_NONE, NULL, 0x00,
3834
14
            NULL, HFILL }
3835
14
        },
3836
14
        { &hf_btl2cap_le_sdu_fragment,
3837
14
        { "SDU fragment", "btl2cap.le_sdu.fragment",
3838
14
            FT_FRAMENUM, BASE_NONE, NULL, 0x00,
3839
14
            NULL, HFILL }
3840
14
        },
3841
14
        { &hf_btl2cap_le_sdu_fragment_overlap,
3842
14
        { "SDU fragment overlap", "btl2cap.le_sdu.fragment.overlap",
3843
14
            FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3844
14
            NULL, HFILL }
3845
14
        },
3846
14
        { &hf_btl2cap_le_sdu_fragment_overlap_conflicts,
3847
14
        { "SDU fragment overlapping with conflicting data", "btl2cap.le_sdu.fragment.overlap.conflicts",
3848
14
            FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3849
14
            NULL, HFILL }
3850
14
        },
3851
14
        { &hf_btl2cap_le_sdu_fragment_multiple_tails,
3852
14
        { "SDU has multiple tail fragments", "btl2cap.le_sdu.fragment.multiple_tails",
3853
14
            FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3854
14
            NULL, HFILL }
3855
14
        },
3856
14
        { &hf_btl2cap_le_sdu_fragment_too_long_fragment,
3857
14
        { "SDU fragment too long", "btl2cap.le_sdu.fragment.too_long_fragment",
3858
14
            FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3859
14
            NULL, HFILL }
3860
14
        },
3861
14
        { &hf_btl2cap_le_sdu_fragment_error,
3862
14
        { "SDU defragmentation error", "btl2cap.le_sdu.fragment.error",
3863
14
            FT_FRAMENUM, BASE_NONE, NULL, 0x00,
3864
14
            NULL, HFILL }
3865
14
        },
3866
14
        { &hf_btl2cap_le_sdu_fragment_count,
3867
14
        { "SDU fragment count", "btl2cap.le_sdu.fragment.count",
3868
14
            FT_UINT32, BASE_DEC, NULL, 0x00,
3869
14
            NULL, HFILL }
3870
14
        },
3871
14
        { &hf_btl2cap_le_sdu_reassembled_in,
3872
14
        { "Reassembled in", "btl2cap.le_sdu.reassembled.in",
3873
14
            FT_FRAMENUM, BASE_NONE, NULL, 0x00,
3874
14
            NULL, HFILL }
3875
14
        },
3876
14
        { &hf_btl2cap_le_sdu_reassembled_length,
3877
14
        { "Reassembled SDU length", "btl2cap.le_sdu.reassembled.length",
3878
14
            FT_UINT32, BASE_DEC, NULL, 0x00,
3879
14
            NULL, HFILL }
3880
14
        },
3881
14
        { &hf_btl2cap_le_sdu_length,
3882
14
        { "SDU Length", "btl2cap.le_sdu_length",
3883
14
            FT_UINT16, BASE_DEC, NULL, 0x00,
3884
14
            NULL, HFILL }
3885
14
        },
3886
3887
14
    };
3888
3889
    /* Setup protocol subtree array */
3890
14
    static int *ett[] = {
3891
14
        &ett_btl2cap,
3892
14
        &ett_btl2cap_cmd,
3893
14
        &ett_btl2cap_option,
3894
14
        &ett_btl2cap_extfeatures,
3895
14
        &ett_btl2cap_fixedchans,
3896
14
        &ett_btl2cap_control,
3897
14
        &ett_btl2cap_le_sdu_fragment,
3898
14
        &ett_btl2cap_le_sdu_fragments
3899
14
    };
3900
3901
14
    static ei_register_info ei[] = {
3902
14
        { &ei_btl2cap_parameter_mismatch, { "btl2cap.parameter_mismatch", PI_PROTOCOL, PI_WARN, "Parameter mismatch", EXPFILL }},
3903
14
        { &ei_btl2cap_sdulength_bad, { "btl2cap.sdulength.bad", PI_MALFORMED, PI_WARN, "SDU length bad", EXPFILL }},
3904
14
        { &ei_btl2cap_length_bad, { "btl2cap.length.bad", PI_MALFORMED, PI_WARN, "Length too short", EXPFILL }},
3905
14
        { &ei_btl2cap_fcs_bad, { "btl2cap.fcs.bad", PI_CHECKSUM, PI_WARN, "Bad FCS", EXPFILL }},
3906
14
        { &ei_btl2cap_unknown_command_code, { "btl2cap.unknown_command_code", PI_PROTOCOL, PI_WARN, "Unknown Command Code", EXPFILL }},
3907
14
    };
3908
3909
    /* Decode As handling */
3910
14
    static build_valid_func btl2cap_cid_da_build_value[1] = {btl2cap_cid_value};
3911
14
    static decode_as_value_t btl2cap_cid_da_values = {btl2cap_cid_prompt, 1, btl2cap_cid_da_build_value};
3912
14
    static decode_as_t btl2cap_cid_da = {"btl2cap", "btl2cap.cid", 1, 0, &btl2cap_cid_da_values, NULL, NULL,
3913
14
                                 decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL, NULL, NULL };
3914
3915
14
    static build_valid_func btl2cap_psm_da_build_value[1] = {btl2cap_psm_value};
3916
14
    static decode_as_value_t btl2cap_psm_da_values = {btl2cap_psm_prompt, 1, btl2cap_psm_da_build_value};
3917
14
    static decode_as_t btl2cap_psm_da = {"btl2cap", "btl2cap.psm", 1, 0, &btl2cap_psm_da_values, NULL, NULL,
3918
14
                                 decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL, NULL, NULL };
3919
3920
    /* Register the protocol name and description */
3921
14
    proto_btl2cap = proto_register_protocol("Bluetooth L2CAP Protocol", "BT L2CAP", "btl2cap");
3922
3923
14
    register_dissector("btl2cap", dissect_btl2cap, proto_btl2cap);
3924
3925
    /* subdissector code */
3926
14
    l2cap_psm_dissector_table = register_dissector_table("btl2cap.psm", "BT L2CAP PSM", proto_btl2cap, FT_UINT16, BASE_HEX);
3927
14
    l2cap_cid_dissector_table = register_dissector_table("btl2cap.cid", "BT L2CAP CID", proto_btl2cap, FT_UINT16, BASE_HEX);
3928
3929
    /* Required function calls to register the header fields and subtrees used */
3930
14
    proto_register_field_array(proto_btl2cap, hf, array_length(hf));
3931
14
    proto_register_subtree_array(ett, array_length(ett));
3932
14
    expert_btl2cap = expert_register_protocol(proto_btl2cap);
3933
14
    expert_register_field_array(expert_btl2cap, ei, array_length(ei));
3934
3935
14
    cmd_ident_to_psm_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
3936
14
    cid_to_psm_table     = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
3937
3938
14
    register_decode_as(&btl2cap_cid_da);
3939
14
    register_decode_as(&btl2cap_psm_da);
3940
3941
14
    reassembly_table_register(&btl2cap_le_sdu_reassembly_table,
3942
14
        &addresses_reassembly_table_functions);
3943
14
}
3944
3945
3946
void
3947
proto_reg_handoff_btl2cap(void)
3948
14
{
3949
14
}
3950
3951
/*
3952
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
3953
 *
3954
 * Local variables:
3955
 * c-basic-offset: 4
3956
 * tab-width: 8
3957
 * indent-tabs-mode: nil
3958
 * End:
3959
 *
3960
 * vi: set shiftwidth=4 tabstop=8 expandtab:
3961
 * :indentSize=4:tabSize=8:noTabs=true:
3962
 */