1 /* packet-btbrlmp.c
2 * Routines for Bluetooth LMP dissection
3 * Copyright 2009, Michael Ossmann <[email protected]>
4 *
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <[email protected]>
7 * Copyright 1998 Gerald Combs
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #else
27 #include <wireshark/config.h>
28 #endif
29
30 #include <wireshark/config.h> /* needed for epan/gcc-4.x */
31 #include <epan/packet.h>
32 #include <epan/prefs.h>
33
34 /* LMP opcodes */
35 #define LMP_NAME_REQ 1
36 #define LMP_NAME_RES 2
37 #define LMP_ACCEPTED 3
38 #define LMP_NOT_ACCEPTED 4
39 #define LMP_CLKOFFSET_REQ 5
40 #define LMP_CLKOFFSET_RES 6
41 #define LMP_DETACH 7
42 #define LMP_IN_RAND 8
43 #define LMP_COMB_KEY 9
44 #define LMP_UNIT_KEY 10
45 #define LMP_AU_RAND 11
46 #define LMP_SRES 12
47 #define LMP_TEMP_RAND 13
48 #define LMP_TEMP_KEY 14
49 #define LMP_ENCRYPTION_MODE_REQ 15
50 #define LMP_ENCRYPTION_KEY_SIZE_REQ 16
51 #define LMP_START_ENCRYPTION_REQ 17
52 #define LMP_STOP_ENCRYPTION_REQ 18
53 #define LMP_SWITCH_REQ 19
54 #define LMP_HOLD 20
55 #define LMP_HOLD_REQ 21
56 #define LMP_SNIFF_REQ 23
57 #define LMP_UNSNIFF_REQ 24
58 #define LMP_PARK_REQ 25
59 #define LMP_SET_BROADCAST_SCAN_WINDOW 27
60 #define LMP_MODIFY_BEACON 28
61 #define LMP_UNPARK_BD_ADDR_REQ 29
62 #define LMP_UNPARK_PM_ADDR_REQ 30
63 #define LMP_INCR_POWER_REQ 31
64 #define LMP_DECR_POWER_REQ 32
65 #define LMP_MAX_POWER 33
66 #define LMP_MIN_POWER 34
67 #define LMP_AUTO_RATE 35
68 #define LMP_PREFERRED_RATE 36
69 #define LMP_VERSION_REQ 37
70 #define LMP_VERSION_RES 38
71 #define LMP_FEATURES_REQ 39
72 #define LMP_FEATURES_RES 40
73 #define LMP_QUALITY_OF_SERVICE 41
74 #define LMP_QUALITY_OF_SERVICE_REQ 42
75 #define LMP_SCO_LINK_REQ 43
76 #define LMP_REMOVE_SCO_LINK_REQ 44
77 #define LMP_MAX_SLOT 45
78 #define LMP_MAX_SLOT_REQ 46
79 #define LMP_TIMING_ACCURACY_REQ 47
80 #define LMP_TIMING_ACCURACY_RES 48
81 #define LMP_SETUP_COMPLETE 49
82 #define LMP_USE_SEMI_PERMANENT_KEY 50
83 #define LMP_HOST_CONNECTION_REQ 51
84 #define LMP_SLOT_OFFSET 52
85 #define LMP_PAGE_MODE_REQ 53
86 #define LMP_PAGE_SCAN_MODE_REQ 54
87 #define LMP_SUPERVISION_TIMEOUT 55
88 #define LMP_TEST_ACTIVATE 56
89 #define LMP_TEST_CONTROL 57
90 #define LMP_ENCRYPTION_KEY_SIZE_MASK_REQ 58
91 #define LMP_ENCRYPTION_KEY_SIZE_MASK_RES 59
92 #define LMP_SET_AFH 60
93 #define LMP_ENCAPSULATED_HEADER 61
94 #define LMP_ENCAPSULATED_PAYLOAD 62
95 #define LMP_SIMPLE_PAIRING_CONFIRM 63
96 #define LMP_SIMPLE_PAIRING_NUMBER 64
97 #define LMP_DHKEY_CHECK 65
98 #define LMP_ESCAPE_1 124
99 #define LMP_ESCAPE_2 125
100 #define LMP_ESCAPE_3 126
101 #define LMP_ESCAPE_4 127
102
103 /* LMP extended opcodes */
104 #define LMP_ACCEPTED_EXT 1
105 #define LMP_NOT_ACCEPTED_EXT 2
106 #define LMP_FEATURES_REQ_EXT 3
107 #define LMP_FEATURES_RES_EXT 4
108 #define LMP_PACKET_TYPE_TABLE_REQ 11
109 #define LMP_ESCO_LINK_REQ 12
110 #define LMP_REMOVE_ESCO_LINK_REQ 13
111 #define LMP_CHANNEL_CLASSIFICATION_REQ 16
112 #define LMP_CHANNEL_CLASSIFICATION 17
113 #define LMP_SNIFF_SUBRATING_REQ 21
114 #define LMP_SNIFF_SUBRATING_RES 22
115 #define LMP_PAUSE_ENCRYPTION_REQ 23
116 #define LMP_RESUME_ENCRYPTION_REQ 24
117 #define LMP_IO_CAPABILITY_REQ 25
118 #define LMP_IO_CAPABILITY_RES 26
119 #define LMP_NUMERIC_COMPARISON_FAILED 27
120 #define LMP_PASSKEY_FAILED 28
121 #define LMP_OOB_FAILED 29
122 #define LMP_KEYPRESS_NOTIFICATION 30
123 #define LMP_POWER_CONTROL_REQ 31
124 #define LMP_POWER_CONTROL_RES 32
125
126 /* initialize the protocol and registered fields */
127 static int proto_btbrlmp = -1;
128 static int hf_lmp_accscheme = -1;
129 static int hf_lmp_afhchmap = -1;
130 static int hf_lmp_afhclass = -1;
131 static int hf_lmp_afhinst = -1;
132 static int hf_lmp_afhmaxintvl = -1;
133 static int hf_lmp_afhminintvl = -1;
134 static int hf_lmp_afhmode = -1;
135 static int hf_lmp_afhrptmode = -1;
136 static int hf_lmp_airmode = -1;
137 static int hf_lmp_araddr = -1;
138 static int hf_lmp_authreqs = -1;
139 static int hf_lmp_authres = -1;
140 static int hf_lmp_bdaddr = -1;
141 static int hf_lmp_bdaddr1 = -1;
142 static int hf_lmp_bdaddr2 = -1;
143 static int hf_lmp_bsw = -1;
144 static int hf_lmp_clkoffset = -1;
145 static int hf_lmp_commit = -1;
146 static int hf_lmp_confirm = -1;
147 static int hf_lmp_compid = -1;
148 static int hf_lmp_cryptmode = -1;
149 static int hf_lmp_daccess = -1;
150 static int hf_lmp_db = -1;
151 static int hf_lmp_dbsleep = -1;
152 static int hf_lmp_deltab = -1;
153 static int hf_lmp_desco = -1;
154 static int hf_lmp_drift = -1;
155 static int hf_lmp_dsco = -1;
156 static int hf_lmp_dsniff = -1;
157 static int hf_lmp_encdata = -1;
158 static int hf_lmp_enclen = -1;
159 static int hf_lmp_encmaj = -1;
160 static int hf_lmp_encmin = -1;
161 static int hf_lmp_eop = -1;
162 static int hf_lmp_eopinre = -1;
163 static int hf_lmp_escolenms = -1;
164 static int hf_lmp_escolensm = -1;
165 static int hf_lmp_escotypems = -1;
166 static int hf_lmp_escotypesm = -1;
167 static int hf_lmp_err = -1;
168 static int hf_lmp_escohdl = -1;
169 static int hf_lmp_escoltaddr = -1;
170 static int hf_lmp_features = -1;
171 static int hf_lmp_fpage = -1;
172 static int hf_lmp_htime = -1;
173 static int hf_lmp_hinst = -1;
174 static int hf_lmp_hopmode = -1;
175 static int hf_lmp_iocaps = -1;
176 static int hf_lmp_jitter = -1;
177 static int hf_lmp_key = -1;
178 static int hf_lmp_keysz = -1;
179 static int hf_lmp_ksmask = -1;
180 static int hf_lmp_ltaddr1 = -1;
181 static int hf_lmp_ltaddr2 = -1;
182 static int hf_lmp_ltaddr3 = -1;
183 static int hf_lmp_ltaddr4 = -1;
184 static int hf_lmp_ltaddr5 = -1;
185 static int hf_lmp_ltaddr6 = -1;
186 static int hf_lmp_ltaddr7 = -1;
187 static int hf_lmp_maccess = -1;
188 static int hf_lmp_maxslots = -1;
189 static int hf_lmp_maxsp = -1;
190 static int hf_lmp_maxss = -1;
191 static int hf_lmp_minsmt = -1;
192 static int hf_lmp_naccslots = -1;
193 static int hf_lmp_namefrag = -1;
194 static int hf_lmp_namelen = -1;
195 static int hf_lmp_nameoffset = -1;
196 static int hf_lmp_nb = -1;
197 static int hf_lmp_nbc = -1;
198 static int hf_lmp_nbsleep = -1;
199 static int hf_lmp_negstate = -1;
200 static int hf_lmp_nonce = -1;
201 static int hf_lmp_nottype = -1;
202 static int hf_lmp_npoll = -1;
203 static int hf_lmp_oobauthdata = -1;
204 static int hf_lmp_op = -1;
205 static int hf_lmp_opinre = -1;
206 static int hf_lmp_pagesch = -1;
207 static int hf_lmp_pcmode = -1;
208 static int hf_lmp_pkttype = -1;
209 static int hf_lmp_pkttypetbl = -1;
210 static int hf_lmp_pmaddr = -1;
211 static int hf_lmp_pmaddr1 = -1;
212 static int hf_lmp_pmaddr2 = -1;
213 static int hf_lmp_pmaddr3 = -1;
214 static int hf_lmp_pmaddr4 = -1;
215 static int hf_lmp_pmaddr5 = -1;
216 static int hf_lmp_pmaddr6 = -1;
217 static int hf_lmp_pmaddr7 = -1;
218 static int hf_lmp_pollintvl = -1;
219 static int hf_lmp_pollper = -1;
220 static int hf_lmp_pssettings = -1;
221 static int hf_lmp_pwradjreq = -1;
222 static int hf_lmp_pwradjres = -1;
223 static int hf_lmp_pwradj_8dpsk = -1;
224 static int hf_lmp_pwradj_dqpsk = -1;
225 static int hf_lmp_pwradj_gfsk = -1;
226 static int hf_lmp_rand = -1;
227 static int hf_lmp_rate = -1;
228 static int hf_lmp_rate_fec = -1;
229 static int hf_lmp_rate_size = -1;
230 static int hf_lmp_rate_type = -1;
231 static int hf_lmp_rate_edrsize = -1;
232 static int hf_lmp_rxfreq = -1;
233 static int hf_lmp_scohdl = -1;
234 static int hf_lmp_scopkt = -1;
235 static int hf_lmp_slotoffset = -1;
236 static int hf_lmp_sniffatt = -1;
237 static int hf_lmp_sniffsi = -1;
238 static int hf_lmp_sniffto = -1;
239 static int hf_lmp_subversnr = -1;
240 static int hf_lmp_suptimeout = -1;
241 static int hf_lmp_swinst = -1;
242 static int hf_lmp_taccess = -1;
243 static int hf_lmp_tb = -1;
244 static int hf_lmp_tesco = -1;
245 static int hf_lmp_testlen = -1;
246 static int hf_lmp_testscen = -1;
247 static int hf_lmp_tid = -1;
248 static int hf_lmp_timectrl = -1;
249 static int hf_lmp_time_change = -1;
250 static int hf_lmp_time_init = -1;
251 static int hf_lmp_time_accwin = -1;
252 static int hf_lmp_tsco = -1;
253 static int hf_lmp_tsniff = -1;
254 static int hf_lmp_txfreq = -1;
255 static int hf_lmp_versnr = -1;
256 static int hf_lmp_wesco = -1;
257
258 /* timing control flags */
259 static const int *timectrl_fields[] = {
260 &hf_lmp_time_change,
261 &hf_lmp_time_init,
262 &hf_lmp_time_accwin,
263 /* bits 3-7 reserved */
264 NULL
265 };
266
267 static const true_false_string time_change = {
268 "timing change",
269 "no timing change"
270 };
271
272 static const true_false_string time_init = {
273 "use initialization 2",
274 "use initialization 1"
275 };
276
277 static const true_false_string time_accwin = {
278 "no access window",
279 "access window"
280 };
281
282 static const true_false_string fec = {
283 "do not use FEC",
284 "use FEC"
285 };
286
287 static const true_false_string tid = {
288 "transaction initiated by slave",
289 "transaction initiated by master"
290 };
291
292 /* short LMP opcodes */
293 static const value_string opcode[] = {
294 { LMP_NAME_REQ, "LMP_name_req" },
295 { LMP_NAME_RES, "LMP_name_res" },
296 { LMP_ACCEPTED, "LMP_accepted" },
297 { LMP_NOT_ACCEPTED, "LMP_not_accepted" },
298 { LMP_CLKOFFSET_REQ, "LMP_clkoffset_req" },
299 { LMP_CLKOFFSET_RES, "LMP_clkoffset_res" },
300 { LMP_DETACH, "LMP_detach" },
301 { LMP_IN_RAND, "LMP_in_rand" },
302 { LMP_COMB_KEY, "LMP_comb_key" },
303 { LMP_UNIT_KEY, "LMP_unit_key" },
304 { LMP_AU_RAND, "LMP_au_rand" },
305 { LMP_SRES, "LMP_sres" },
306 { LMP_TEMP_RAND, "LMP_temp_rand" },
307 { LMP_TEMP_KEY, "LMP_temp_key" },
308 { LMP_ENCRYPTION_MODE_REQ, "LMP_encryption_mode_req" },
309 { LMP_ENCRYPTION_KEY_SIZE_REQ, "LMP_encryption_key_size_req" },
310 { LMP_START_ENCRYPTION_REQ, "LMP_start_encryption_req" },
311 { LMP_STOP_ENCRYPTION_REQ, "LMP_stop_encryption_req" },
312 { LMP_SWITCH_REQ, "LMP_switch_req" },
313 { LMP_HOLD, "LMP_hold" },
314 { LMP_HOLD_REQ, "LMP_hold_req" },
315 { LMP_SNIFF_REQ, "LMP_sniff_req" },
316 { LMP_UNSNIFF_REQ, "LMP_unsniff_req" },
317 { LMP_PARK_REQ, "LMP_park_req" },
318 { LMP_SET_BROADCAST_SCAN_WINDOW, "LMP_set_broadcast_scan_window" },
319 { LMP_MODIFY_BEACON, "LMP_modify_beacon" },
320 { LMP_UNPARK_BD_ADDR_REQ, "LMP_unpark_BD_ADDR_req" },
321 { LMP_UNPARK_PM_ADDR_REQ, "LMP_unpark_PM_ADDR_req" },
322 { LMP_INCR_POWER_REQ, "LMP_incr_power_req" },
323 { LMP_DECR_POWER_REQ, "LMP_decr_power_req" },
324 { LMP_MAX_POWER, "LMP_max_power" },
325 { LMP_MIN_POWER, "LMP_min_power" },
326 { LMP_AUTO_RATE, "LMP_auto_rate" },
327 { LMP_PREFERRED_RATE, "LMP_preferred_rate" },
328 { LMP_VERSION_REQ, "LMP_version_req" },
329 { LMP_VERSION_RES, "LMP_version_res" },
330 { LMP_FEATURES_REQ, "LMP_features_req" },
331 { LMP_FEATURES_RES, "LMP_features_res" },
332 { LMP_QUALITY_OF_SERVICE, "LMP_quality_of_service" },
333 { LMP_QUALITY_OF_SERVICE_REQ, "LMP_quality_of_service_req" },
334 { LMP_SCO_LINK_REQ, "LMP_SCO_link_req" },
335 { LMP_REMOVE_SCO_LINK_REQ, "LMP_remove_SCO_link_req" },
336 { LMP_MAX_SLOT, "LMP_max_slot" },
337 { LMP_MAX_SLOT_REQ, "LMP_max_slot_req" },
338 { LMP_TIMING_ACCURACY_REQ, "LMP_timing_accuracy_req" },
339 { LMP_TIMING_ACCURACY_RES, "LMP_timing_accuracy_res" },
340 { LMP_SETUP_COMPLETE, "LMP_setup_complete" },
341 { LMP_USE_SEMI_PERMANENT_KEY, "LMP_use_semi_permanent_key" },
342 { LMP_HOST_CONNECTION_REQ, "LMP_host_connection_req" },
343 { LMP_SLOT_OFFSET, "LMP_slot_offset" },
344 { LMP_PAGE_MODE_REQ, "LMP_page_mode_req" },
345 { LMP_PAGE_SCAN_MODE_REQ, "LMP_page_scan_mode_req" },
346 { LMP_SUPERVISION_TIMEOUT, "LMP_supervision_timeout" },
347 { LMP_TEST_ACTIVATE, "LMP_test_activate" },
348 { LMP_TEST_CONTROL, "LMP_test_control" },
349 { LMP_ENCRYPTION_KEY_SIZE_MASK_REQ, "LMP_encryption_key_size_mask_req" },
350 { LMP_ENCRYPTION_KEY_SIZE_MASK_RES, "LMP_encryption_key_size_mask_res" },
351 { LMP_SET_AFH, "LMP_set_AFH" },
352 { LMP_ENCAPSULATED_HEADER, "LMP_encapsulated_header" },
353 { LMP_ENCAPSULATED_PAYLOAD, "LMP_encapsulated_payload" },
354 { LMP_SIMPLE_PAIRING_CONFIRM, "LMP_Simple_Pairing_Confirm" },
355 { LMP_SIMPLE_PAIRING_NUMBER, "LMP_Simple_Pairing_Number" },
356 { LMP_DHKEY_CHECK, "LMP_DHkey_Check" },
357 { LMP_ESCAPE_1, "Escape 1" },
358 { LMP_ESCAPE_2, "Escape 2" },
359 { LMP_ESCAPE_3, "Escape 3" },
360 { LMP_ESCAPE_4, "Escape 4" },
361 { 0, NULL }
362 };
363
364 /* extended LMP opcodes */
365 static const value_string ext_opcode[] = {
366 { LMP_ACCEPTED_EXT, "LMP_accepted_ext" },
367 { LMP_NOT_ACCEPTED_EXT, "LMP_not_accepted_ext" },
368 { LMP_FEATURES_REQ_EXT, "LMP_features_req_ext" },
369 { LMP_FEATURES_RES_EXT, "LMP_features_res_ext" },
370 { LMP_PACKET_TYPE_TABLE_REQ, "LMP_packet_type_table_req" },
371 { LMP_ESCO_LINK_REQ, "LMP_eSCO_link_req" },
372 { LMP_REMOVE_ESCO_LINK_REQ, "LMP_remove_eSCO_link_req" },
373 { LMP_CHANNEL_CLASSIFICATION_REQ, "LMP_channel_classification_req" },
374 { LMP_CHANNEL_CLASSIFICATION, "LMP_channel_classification" },
375 { LMP_SNIFF_SUBRATING_REQ, "LMP_sniff_subrating_req" },
376 { LMP_SNIFF_SUBRATING_RES, "LMP_sniff_subrating_res" },
377 { LMP_PAUSE_ENCRYPTION_REQ, "LMP_pause_encryption_req" },
378 { LMP_RESUME_ENCRYPTION_REQ, "LMP_resume_encryption_req" },
379 { LMP_IO_CAPABILITY_REQ, "LMP_IO_Capability_req" },
380 { LMP_IO_CAPABILITY_RES, "LMP_IO_Capability_res" },
381 { LMP_NUMERIC_COMPARISON_FAILED, "LMP_numeric_comparison_failed" },
382 { LMP_PASSKEY_FAILED, "LMP_passkey_failed" },
383 { LMP_OOB_FAILED, "LMP_oob_failed" },
384 { LMP_KEYPRESS_NOTIFICATION, "LMP_keypress_notification" },
385 { LMP_POWER_CONTROL_REQ, "LMP_power_control_req" },
386 { LMP_POWER_CONTROL_RES, "LMP_power_control_res" },
387 { 0, NULL }
388 };
389
390 /* LMP error codes */
391 static const value_string error_code[] = {
392 { 0x00, "Success" },
393 { 0x01, "Unknown HCI Command" },
394 { 0x02, "Unknown Connection Identifier" },
395 { 0x03, "Hardware Failure" },
396 { 0x04, "Page Timeout" },
397 { 0x05, "Authentication Failure" },
398 { 0x06, "PIN or Key Missing" },
399 { 0x07, "Memory Capacity Exceeded" },
400 { 0x08, "Connection Timeout" },
401 { 0x09, "Connection Limit Exceeded" },
402 { 0x0A, "Synchronous Connection Limit To A Device Exceeded" },
403 { 0x0B, "ACL Connection Already Exists" },
404 { 0x0C, "Command Disallowed" },
405 { 0x0D, "Connection Rejected due to Limited Resources" },
406 { 0x0E, "Connection Rejected Due To Security Reasons" },
407 { 0x0F, "Connection Rejected due to Unacceptable BD_ADDR" },
408 { 0x10, "Connection Accept Timeout Exceeded" },
409 { 0x11, "Unsupported Feature or Parameter Value" },
410 { 0x12, "Invalid HCI Command Parameters" },
411 { 0x13, "Remote User Terminated Connection" },
412 { 0x14, "Remote Device Terminated Connection due to Low Resources" },
413 { 0x15, "Remote Device Terminated Connection due to Power Off" },
414 { 0x16, "Connection Terminated By Local Host" },
415 { 0x17, "Repeated Attempts" },
416 { 0x18, "Pairing Not Allowed" },
417 { 0x19, "Unknown LMP PDU" },
418 { 0x1A, "Unsupported Remote Feature / Unsupported LMP Feature" },
419 { 0x1B, "SCO Offset Rejected" },
420 { 0x1C, "SCO Interval Rejected" },
421 { 0x1D, "SCO Air Mode Rejected" },
422 { 0x1E, "Invalid LMP Parameters" },
423 { 0x1F, "Unspecified Error" },
424 { 0x20, "Unsupported LMP Parameter Value" },
425 { 0x21, "Role Change Not Allowed" },
426 { 0x22, "LMP Response Timeout" },
427 { 0x23, "LMP Error Transaction Collision" },
428 { 0x24, "LMP PDU Not Allowed" },
429 { 0x25, "Encryption Mode Not Acceptable" },
430 { 0x26, "Link Key Can Not be Changed" },
431 { 0x27, "Requested QoS Not Supported" },
432 { 0x28, "Instant Passed" },
433 { 0x29, "Pairing With Unit Key Not Supported" },
434 { 0x2A, "Different Transaction Collision" },
435 { 0x2B, "Reserved" },
436 { 0x2C, "QoS Unacceptable Parameter" },
437 { 0x2D, "QoS Rejected" },
438 { 0x2E, "Channel Classification Not Supported" },
439 { 0x2F, "Insufficient Security" },
440 { 0x30, "Parameter Out Of Mandatory Range" },
441 { 0x31, "Reserved" },
442 { 0x32, "Role Switch Pending" },
443 { 0x33, "Reserved" },
444 { 0x34, "Reserved Slot Violation" },
445 { 0x35, "Role Switch Failed" },
446 { 0x36, "Extended Inquiry Response Too Large" },
447 { 0x37, "Secure Simple Pairing Not Supported By Host." },
448 { 0x38, "Host Busy - Pairing" },
449 { 0x39, "Connection Rejected due to No Suitable Channel Found" },
450 { 0, NULL }
451 };
452
453 static const value_string encryption_mode[] = {
454 { 0, "no encryption" },
455 { 1, "encryption" },
456 { 2, "encryption" },
457 /* 3 - 255 reserved */
458 { 0, NULL }
459 };
460
461 static const value_string access_scheme[] = {
462 { 0, "polling technique" },
463 /* 1 - 15 reserved */
464 { 0, NULL }
465 };
466
467 static const value_string packet_size[] = {
468 { 0, "no packet-size preference available" },
469 { 1, "use 1-slot packets" },
470 { 2, "use 3-slot packets" },
471 { 3, "use 5-slot packets" },
472 { 0, NULL }
473 };
474
475 static const value_string edr_type[] = {
476 { 0, "use DM1 packets" },
477 { 1, "use 2 Mbps packets" },
478 { 2, "use 3 Mbps packets" },
479 /* 3 reserved */
480 { 0, NULL }
481 };
482
483 static const value_string versnr[] = {
484 { 0, "Bluetooth Core Specification 1.0b" },
485 { 1, "Bluetooth Core Specification 1.1" },
486 { 2, "Bluetooth Core Specification 1.2" },
487 { 3, "Bluetooth Core Specification 2.0 + EDR" },
488 { 4, "Bluetooth Core Specification 2.1 + EDR" },
489 { 5, "Bluetooth Core Specification 3.0 + HS" },
490 /* 6 - 255 reserved */
491 { 0, NULL }
492 };
493
494 static const value_string compid[] = {
495 { 0, "Ericsson Technology Licensing" },
496 { 1, "Nokia Mobile Phones" },
497 { 2, "Intel Corp." },
498 { 3, "IBM Corp." },
499 { 4, "Toshiba Corp." },
500 { 5, "3Com" },
501 { 6, "Microsoft" },
502 { 7, "Lucent" },
503 { 8, "Motorola" },
504 { 9, "Infineon Technologies AG" },
505 { 10, "Cambridge Silicon Radio" },
506 { 11, "Silicon Wave" },
507 { 12, "Digianswer A/S" },
508 { 13, "Texas Instruments Inc." },
509 { 14, "Parthus Technologies Inc." },
510 { 15, "Broadcom Corporation" },
511 { 16, "Mitel Semiconductor" },
512 { 17, "Widcomm, Inc." },
513 { 18, "Zeevo, Inc." },
514 { 19, "Atmel Corporation" },
515 { 20, "Mitsubishi Electric Corporation" },
516 { 21, "RTX Telecom A/S" },
517 { 22, "KC Technology Inc." },
518 { 23, "Newlogic" },
519 { 24, "Transilica, Inc." },
520 { 25, "Rohde & Schwarz GmbH & Co. KG" },
521 { 26, "TTPCom Limited" },
522 { 27, "Signia Technologies, Inc." },
523 { 28, "Conexant Systems Inc." },
524 { 29, "Qualcomm" },
525 { 30, "Inventel" },
526 { 31, "AVM Berlin" },
527 { 32, "BandSpeed, Inc." },
528 { 33, "Mansella Ltd" },
529 { 34, "NEC Corporation" },
530 { 35, "WavePlus Technology Co., Ltd." },
531 { 36, "Alcatel" },
532 { 37, "Philips Semiconductors" },
533 { 38, "C Technologies" },
534 { 39, "Open Interface" },
535 { 40, "R F Micro Devices" },
536 { 41, "Hitachi Ltd" },
537 { 42, "Symbol Technologies, Inc." },
538 { 43, "Tenovis" },
539 { 44, "Macronix International Co. Ltd." },
540 { 45, "GCT Semiconductor" },
541 { 46, "Norwood Systems" },
542 { 47, "MewTel Technology Inc." },
543 { 48, "ST Microelectronics" },
544 { 49, "Synopsys" },
545 { 50, "Red-M (Communications) Ltd" },
546 { 51, "Commil Ltd" },
547 { 52, "Computer Access Technology Corporation (CATC)" },
548 { 53, "Eclipse (HQ Espana) S.L." },
549 { 54, "Renesas Technology Corp." },
550 { 55, "Mobilian Corporation" },
551 { 56, "Terax" },
552 { 57, "Integrated System Solution Corp." },
553 { 58, "Matsushita Electric Industrial Co., Ltd." },
554 { 59, "Gennum Corporation" },
555 { 60, "Research In Motion" },
556 { 61, "IPextreme, Inc." },
557 { 62, "Systems and Chips, Inc" },
558 { 63, "Bluetooth SIG, Inc" },
559 { 64, "Seiko Epson Corporation" },
560 { 65, "Integrated Silicon Solution Taiwan, Inc." },
561 { 66, "CONWISE Technology Corporation Ltd" },
562 { 67, "PARROT SA" },
563 { 68, "Socket Mobile" },
564 { 69, "Atheros Communications, Inc." },
565 { 70, "MediaTek, Inc." },
566 { 71, "Bluegiga (tentative)" },
567 { 72, "Marvell Technology Group Ltd." },
568 { 73, "3DSP Corporation" },
569 { 74, "Accel Semiconductor Ltd." },
570 { 75, "Continental Automotive Systems" },
571 { 76, "Apple, Inc." },
572 { 77, "Staccato Communications, Inc." },
573 { 78, "Avago Technologies" },
574 { 79, "APT Ltd." },
575 { 80, "SiRF Technology, Inc." },
576 { 81, "Tzero Technologies, Inc." },
577 { 82, "J&M Corporation" },
578 { 83, "Free2move AB" },
579 /* 84 - 65534 reserved */
580 { 65535, "test" },
581 { 0, NULL }
582 };
583
584 static const value_string sco_packet[] = {
585 { 0, "HV1" },
586 { 1, "HV2" },
587 { 2, "HV3" },
588 /* 3 - 255 reserved */
589 { 0, NULL }
590 };
591
592 static const value_string air_mode[] = {
593 { 0, "mu-law log" },
594 { 1, "A-law log" },
595 { 2, "CVSD" },
596 { 3, "transparent data" },
597 /* 4 - 255 reserved */
598 { 0, NULL }
599 };
600
601 static const value_string paging_scheme[] = {
602 { 0, "mandatory scheme" },
603 /* 1 - 255 reserved */
604 { 0, NULL }
605 };
606
607 static const value_string paging_scheme_settings[] = {
608 /* for mandatory scheme: */
609 { 0, "R0" },
610 { 1, "R1" },
611 { 2, "R2" },
612 /* 3 - 255 reserved */
613 { 0, NULL }
614 };
615
616 static const value_string afh_mode[] = {
617 { 0, "AFH disabled" },
618 { 1, "AFH enabled" },
619 /* 2 - 255 reserved */
620 { 0, NULL }
621 };
622
623 static const value_string features_page[] = {
624 { 0, "standard features" },
625 /* 1 - 255 other feature pages */
626 { 0, NULL }
627 };
628
629 static const value_string packet_type_table[] = {
630 { 0, "1 Mbps only" },
631 { 1, "2/3 Mbps" },
632 /* 2 - 255 reserved */
633 { 0, NULL }
634 };
635
636 static const value_string negotiation_state[] = {
637 { 0, "Initiate negotiation" },
638 { 1, "The latest received set of negotiable parameters were possible but these parameters are preferred." },
639 { 2, "The latest received set of negotiable parameters would cause a reserved slot violation." },
640 { 3, "The latest received set of negotiable parameters would cause a latency violation." },
641 { 4, "The latest received set of negotiable parameters are not supported." },
642 /* 5 - 255 reserved */
643 { 0, NULL }
644 };
645
646 static const value_string afh_reporting_mode[] = {
647 { 0, "AFH reporting disabled" },
648 { 1, "AFH reporting enabled" },
649 /* 2 - 255 reserved */
650 { 0, NULL }
651 };
652
653 static const value_string io_capabilities[] = {
654 { 0, "Display Only" },
655 { 1, "Display Yes/No" },
656 { 2, "Keyboard Only" },
657 { 3, "No Input/No Output" },
658 /* 4 - 255 reserved */
659 { 0, NULL }
660 };
661
662 static const value_string oob_auth_data[] = {
663 { 0, "No OOB Authentication Data received" },
664 { 1, "OOB Authentication Data received" },
665 /* 2 - 255 reserved */
666 { 0, NULL }
667 };
668
669 static const value_string auth_requirements[] = {
670 { 0x00, "MITM Protection Not Required - No Bonding" },
671 { 0x01, "MITM Protection Required - No Bonding" },
672 { 0x02, "MITM Protection Not Required - Dedicated Bonding" },
673 { 0x03, "MITM Protection Required - Dedicated Bonding" },
674 { 0x04, "MITM Protection Not Required - General Bonding" },
675 { 0x05, "MITM Protection Required - General Bonding" },
676 /* 0x06 - 0xff reserved */
677 { 0, NULL }
678 };
679
680 static const value_string power_adjust_req[] = {
681 { 0, "decrement power one step" },
682 { 1, "increment power one step" },
683 { 2, "increase to maximum power" },
684 /* 3 - 255 reserved */
685 { 0, NULL }
686 };
687
688 static const value_string power_adjust_res[] = {
689 { 0, "not supported" },
690 { 1, "changed one step (not min or max)" },
691 { 2, "max power" },
692 { 3, "min power" },
693 /* 4 - 255 reserved */
694 { 0, NULL }
695 };
696
697 static const value_string test_scenario[] = {
698 { 0, "Pause Test Mode" },
699 { 1, "Transmitter test - 0 pattern" },
700 { 2, "Transmitter test - 1 pattern" },
701 { 3, "Transmitter test - 1010 pattern" },
702 { 4, "Pseudorandom bit sequence" },
703 { 5, "Closed Loop Back - ACL packets" },
704 { 6, "Closed Loop Back - Synchronous packets" },
705 { 7, "ACL Packets without whitening" },
706 { 8, "Synchronous Packets without whitening" },
707 { 9, "Transmitter test - 1111 0000 pattern" },
708 /* 10 - 254 reserved */
709 { 255, "Exit Test Mode" },
710 { 0, NULL }
711 };
712
713 static const value_string hopping_mode[] = {
714 { 0, "RX/TX on single frequency" },
715 { 1, "Normal hopping" },
716 /* 2 - 255 reserved */
717 { 0, NULL }
718 };
719
720 static const value_string power_control_mode[] = {
721 { 0, "fixed TX output power" },
722 { 1, "adaptive power control" },
723 /* 2 - 255 reserved */
724 { 0, NULL }
725 };
726
727 static const value_string esco_packet_type[] = {
728 { 0x00, "NULL/POLL" },
729 { 0x07, "EV3" },
730 { 0x0C, "EV4" },
731 { 0x0D, "EV5" },
732 { 0x26, "2-EV3" },
733 { 0x2C, "2-EV5" },
734 { 0x37, "3-EV3" },
735 { 0x3D, "3-EV5" },
736 /* other values reserved */
737 { 0, NULL }
738 };
739
740 static const value_string notification_value[] = {
741 { 0, "passkey entry started" },
742 { 1, "passkey digit entered" },
743 { 2, "passkey digit erased" },
744 { 3, "passkey cleared" },
745 { 4, "passkey entry completed" },
746 /* 5 - 255 reserved */
747 { 0, NULL }
748 };
749
750 /* initialize the subtree pointers */
751 static gint ett_lmp = -1;
752 static gint ett_lmp_pwradjres = -1;
753 static gint ett_lmp_rate = -1;
754 static gint ett_lmp_timectrl = -1;
755
756 /* LMP PDUs with short opcodes */
757
758 void
dissect_name_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)759 dissect_name_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
760 {
761 DISSECTOR_ASSERT(len == 2);
762 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1);
763
764 proto_tree_add_item(tree, hf_lmp_nameoffset, tvb, offset, 1, ENC_NA);
765 }
766
767 void
dissect_name_res(proto_tree * tree,tvbuff_t * tvb,int offset,int len)768 dissect_name_res(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
769 {
770 DISSECTOR_ASSERT(len == 17);
771 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16);
772
773 proto_tree_add_item(tree, hf_lmp_nameoffset, tvb, offset, 1, ENC_NA);
774 offset += 1;
775
776 proto_tree_add_item(tree, hf_lmp_namelen, tvb, offset, 1, ENC_NA);
777 offset += 1;
778
779 proto_tree_add_item(tree, hf_lmp_namefrag, tvb, offset, 14, ENC_ASCII|ENC_NA);
780 }
781
782 void
dissect_accepted(proto_tree * tree,tvbuff_t * tvb,int offset,int len)783 dissect_accepted(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
784 {
785 DISSECTOR_ASSERT(len == 2);
786 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1);
787
788 proto_tree_add_item(tree, hf_lmp_opinre, tvb, offset, 1, ENC_NA);
789 }
790
791 void
dissect_not_accepted(proto_tree * tree,tvbuff_t * tvb,int offset,int len)792 dissect_not_accepted(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
793 {
794 DISSECTOR_ASSERT(len == 3);
795 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2);
796
797 proto_tree_add_item(tree, hf_lmp_opinre, tvb, offset, 1, ENC_NA);
798 offset += 1;
799
800 proto_tree_add_item(tree, hf_lmp_err, tvb, offset, 1, ENC_NA);
801 }
802
803 void
dissect_clkoffset_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)804 dissect_clkoffset_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
805 {
806 DISSECTOR_ASSERT(len == 1);
807 }
808
809 void
dissect_clkoffset_res(proto_tree * tree,tvbuff_t * tvb,int offset,int len)810 dissect_clkoffset_res(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
811 {
812 DISSECTOR_ASSERT(len == 3);
813 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2);
814
815 proto_tree_add_item(tree, hf_lmp_clkoffset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
816 }
817
818 void
dissect_detach(proto_tree * tree,tvbuff_t * tvb,int offset,int len)819 dissect_detach(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
820 {
821 DISSECTOR_ASSERT(len == 2);
822 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1);
823
824 proto_tree_add_item(tree, hf_lmp_err, tvb, offset, 1, ENC_NA);
825 }
826
827 void
dissect_in_rand(proto_tree * tree,tvbuff_t * tvb,int offset,int len)828 dissect_in_rand(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
829 {
830 DISSECTOR_ASSERT(len == 17);
831 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16);
832
833 proto_tree_add_item(tree, hf_lmp_rand, tvb, offset, 16, ENC_NA);
834 }
835
836 void
dissect_comb_key(proto_tree * tree,tvbuff_t * tvb,int offset,int len)837 dissect_comb_key(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
838 {
839 DISSECTOR_ASSERT(len == 17);
840 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16);
841
842 proto_tree_add_item(tree, hf_lmp_rand, tvb, offset, 16, ENC_NA);
843 }
844
845 void
dissect_unit_key(proto_tree * tree,tvbuff_t * tvb,int offset,int len)846 dissect_unit_key(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
847 {
848 DISSECTOR_ASSERT(len == 17);
849 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16);
850
851 proto_tree_add_item(tree, hf_lmp_key, tvb, offset, 16, ENC_NA);
852 }
853
854 void
dissect_au_rand(proto_tree * tree,tvbuff_t * tvb,int offset,int len)855 dissect_au_rand(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
856 {
857 DISSECTOR_ASSERT(len == 17);
858 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16);
859
860 proto_tree_add_item(tree, hf_lmp_rand, tvb, offset, 16, ENC_NA);
861 }
862
863 void
dissect_sres(proto_tree * tree,tvbuff_t * tvb,int offset,int len)864 dissect_sres(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
865 {
866 DISSECTOR_ASSERT(len == 5);
867 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 4);
868
869 proto_tree_add_item(tree, hf_lmp_authres, tvb, offset, 4, ENC_NA);
870 }
871
872 void
dissect_temp_rand(proto_tree * tree,tvbuff_t * tvb,int offset,int len)873 dissect_temp_rand(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
874 {
875 DISSECTOR_ASSERT(len == 17);
876 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16);
877
878 proto_tree_add_item(tree, hf_lmp_rand, tvb, offset, 16, ENC_NA);
879 }
880
881 void
dissect_temp_key(proto_tree * tree,tvbuff_t * tvb,int offset,int len)882 dissect_temp_key(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
883 {
884 DISSECTOR_ASSERT(len == 17);
885 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16);
886
887 proto_tree_add_item(tree, hf_lmp_key, tvb, offset, 16, ENC_NA);
888 }
889
890 void
dissect_encryption_mode_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)891 dissect_encryption_mode_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
892 {
893 DISSECTOR_ASSERT(len == 2);
894 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1);
895
896 proto_tree_add_item(tree, hf_lmp_cryptmode, tvb, offset, 1, ENC_LITTLE_ENDIAN);
897 }
898
899 void
dissect_encryption_key_size_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)900 dissect_encryption_key_size_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
901 {
902 DISSECTOR_ASSERT(len == 2);
903 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1);
904
905 proto_tree_add_item(tree, hf_lmp_keysz, tvb, offset, 1, ENC_LITTLE_ENDIAN);
906 }
907
908 void
dissect_start_encryption_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)909 dissect_start_encryption_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
910 {
911 DISSECTOR_ASSERT(len == 17);
912 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16);
913
914 proto_tree_add_item(tree, hf_lmp_rand, tvb, offset, 16, ENC_NA);
915 }
916
917 void
dissect_stop_encryption_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)918 dissect_stop_encryption_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
919 {
920 DISSECTOR_ASSERT(len == 1);
921 }
922
923 void
dissect_switch_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)924 dissect_switch_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
925 {
926 DISSECTOR_ASSERT(len == 5);
927 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 4);
928
929 proto_tree_add_item(tree, hf_lmp_swinst, tvb, offset, 4, ENC_LITTLE_ENDIAN);
930 }
931
932 void
dissect_hold(proto_tree * tree,tvbuff_t * tvb,int offset,int len)933 dissect_hold(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
934 {
935 DISSECTOR_ASSERT(len == 7);
936 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 6);
937
938 proto_tree_add_item(tree, hf_lmp_htime, tvb, offset, 2, ENC_LITTLE_ENDIAN);
939 offset += 2;
940
941 proto_tree_add_item(tree, hf_lmp_hinst, tvb, offset, 4, ENC_LITTLE_ENDIAN);
942 }
943
944 void
dissect_hold_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)945 dissect_hold_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
946 {
947 DISSECTOR_ASSERT(len == 7);
948 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 6);
949
950 proto_tree_add_item(tree, hf_lmp_htime, tvb, offset, 2, ENC_LITTLE_ENDIAN);
951 offset += 2;
952
953 proto_tree_add_item(tree, hf_lmp_hinst, tvb, offset, 4, ENC_LITTLE_ENDIAN);
954 }
955
956 void
dissect_sniff_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)957 dissect_sniff_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
958 {
959 DISSECTOR_ASSERT(len == 10);
960 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 9);
961
962 proto_tree_add_bitmask(tree, tvb, offset, hf_lmp_timectrl,
963 ett_lmp_timectrl, timectrl_fields, ENC_LITTLE_ENDIAN);
964 offset += 1;
965
966 proto_tree_add_item(tree, hf_lmp_dsniff, tvb, offset, 2, ENC_LITTLE_ENDIAN);
967 offset += 2;
968
969 proto_tree_add_item(tree, hf_lmp_tsniff, tvb, offset, 2, ENC_LITTLE_ENDIAN);
970 offset += 2;
971
972 proto_tree_add_item(tree, hf_lmp_sniffatt, tvb, offset, 2, ENC_LITTLE_ENDIAN);
973 offset += 2;
974
975 proto_tree_add_item(tree, hf_lmp_sniffto, tvb, offset, 2, ENC_LITTLE_ENDIAN);
976 }
977
978 void
dissect_unsniff_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)979 dissect_unsniff_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
980 {
981 DISSECTOR_ASSERT(len == 1);
982 }
983
984 void
dissect_park_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)985 dissect_park_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
986 {
987 DISSECTOR_ASSERT(len == 17);
988 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16);
989
990 proto_tree_add_bitmask(tree, tvb, offset, hf_lmp_timectrl,
991 ett_lmp_timectrl, timectrl_fields, ENC_LITTLE_ENDIAN);
992 offset += 1;
993
994 proto_tree_add_item(tree, hf_lmp_db, tvb, offset, 2, ENC_LITTLE_ENDIAN);
995 offset += 2;
996
997 proto_tree_add_item(tree, hf_lmp_tb, tvb, offset, 2, ENC_LITTLE_ENDIAN);
998 offset += 2;
999
1000 proto_tree_add_item(tree, hf_lmp_nb, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1001 offset += 1;
1002
1003 proto_tree_add_item(tree, hf_lmp_deltab, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1004 offset += 1;
1005
1006 proto_tree_add_item(tree, hf_lmp_pmaddr, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1007 offset += 1;
1008
1009 proto_tree_add_item(tree, hf_lmp_araddr, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1010 offset += 1;
1011
1012 proto_tree_add_item(tree, hf_lmp_nbsleep, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1013 offset += 1;
1014
1015 proto_tree_add_item(tree, hf_lmp_dbsleep, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1016 offset += 1;
1017
1018 proto_tree_add_item(tree, hf_lmp_daccess, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1019 offset += 1;
1020
1021 proto_tree_add_item(tree, hf_lmp_taccess, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1022 offset += 1;
1023
1024 proto_tree_add_item(tree, hf_lmp_naccslots, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1025 offset += 1;
1026
1027 proto_tree_add_item(tree, hf_lmp_npoll, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1028 offset += 1;
1029
1030 proto_tree_add_item(tree, hf_lmp_maccess, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1031 proto_tree_add_item(tree, hf_lmp_accscheme, tvb, offset, 1, ENC_NA);
1032 }
1033
1034 void
dissect_set_broadcast_scan_window(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1035 dissect_set_broadcast_scan_window(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1036 {
1037 int db_present;
1038
1039 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1);
1040
1041 proto_tree_add_bitmask(tree, tvb, offset, hf_lmp_timectrl,
1042 ett_lmp_timectrl, timectrl_fields, ENC_LITTLE_ENDIAN);
1043
1044 /* bit0 of timing control flags indicates presence of db */
1045 db_present = tvb_get_guint8(tvb, offset) & 0x01;
1046 offset += 1;
1047
1048 if (db_present) {
1049 DISSECTOR_ASSERT(len == 6);
1050 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 4);
1051
1052 proto_tree_add_item(tree, hf_lmp_db, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1053 offset += 2;
1054 } else {
1055 DISSECTOR_ASSERT(len == 4);
1056 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2);
1057 }
1058
1059 proto_tree_add_item(tree, hf_lmp_bsw, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1060 }
1061
1062 void
dissect_modify_beacon(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1063 dissect_modify_beacon(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1064 {
1065 int db_present;
1066
1067 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1);
1068
1069 proto_tree_add_bitmask(tree, tvb, offset, hf_lmp_timectrl,
1070 ett_lmp_timectrl, timectrl_fields, ENC_LITTLE_ENDIAN);
1071
1072 /* bit0 of timing control flags indicates presence of db */
1073 db_present = tvb_get_guint8(tvb, offset) & 0x01;
1074 offset += 1;
1075
1076 if (db_present) {
1077 DISSECTOR_ASSERT(len == 13);
1078 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 11);
1079
1080 proto_tree_add_item(tree, hf_lmp_db, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1081 offset += 2;
1082 } else {
1083 DISSECTOR_ASSERT(len == 11);
1084 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 9);
1085 }
1086
1087 proto_tree_add_item(tree, hf_lmp_tb, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1088 offset += 2;
1089
1090 proto_tree_add_item(tree, hf_lmp_nb, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1091 offset += 1;
1092
1093 proto_tree_add_item(tree, hf_lmp_deltab, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1094 offset += 1;
1095
1096 proto_tree_add_item(tree, hf_lmp_daccess, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1097 offset += 1;
1098
1099 proto_tree_add_item(tree, hf_lmp_taccess, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1100 offset += 1;
1101
1102 proto_tree_add_item(tree, hf_lmp_naccslots, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1103 offset += 1;
1104
1105 proto_tree_add_item(tree, hf_lmp_npoll, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1106 offset += 1;
1107
1108 proto_tree_add_item(tree, hf_lmp_maccess, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1109 proto_tree_add_item(tree, hf_lmp_accscheme, tvb, offset, 1, ENC_NA);
1110 }
1111
1112 void
dissect_unpark_bd_addr_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1113 dissect_unpark_bd_addr_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1114 {
1115 int db_present;
1116 proto_item *item;
1117
1118 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1);
1119
1120 proto_tree_add_bitmask(tree, tvb, offset, hf_lmp_timectrl,
1121 ett_lmp_timectrl, timectrl_fields, ENC_LITTLE_ENDIAN);
1122
1123 /* bit0 of timing control flags indicates presence of db */
1124 db_present = tvb_get_guint8(tvb, offset) & 0x01;
1125 offset += 1;
1126
1127 if (db_present) {
1128 DISSECTOR_ASSERT(len == 17);
1129 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 15);
1130
1131 proto_tree_add_item(tree, hf_lmp_db, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1132 offset += 2;
1133 } else {
1134 DISSECTOR_ASSERT(len == 15);
1135 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 13);
1136 }
1137
1138 proto_tree_add_item(tree, hf_lmp_ltaddr1, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1139 proto_tree_add_item(tree, hf_lmp_ltaddr2, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1140 offset += 1;
1141
1142 proto_tree_add_item(tree, hf_lmp_bdaddr1, tvb, offset, 6, ENC_LITTLE_ENDIAN);
1143 offset += 6;
1144
1145 proto_tree_add_item(tree, hf_lmp_bdaddr2, tvb, offset, 6, ENC_LITTLE_ENDIAN);
1146 offset += 6;
1147 }
1148
1149 void
dissect_unpark_pm_addr_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1150 dissect_unpark_pm_addr_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1151 {
1152 int db_present;
1153
1154 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1);
1155
1156 proto_tree_add_bitmask(tree, tvb, offset, hf_lmp_timectrl,
1157 ett_lmp_timectrl, timectrl_fields, ENC_LITTLE_ENDIAN);
1158
1159 /* bit0 of timing control flags indicates presence of db */
1160 db_present = tvb_get_guint8(tvb, offset) & 0x01;
1161 offset += 1;
1162
1163 if (db_present) {
1164 DISSECTOR_ASSERT(len == 15);
1165 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 13);
1166
1167 proto_tree_add_item(tree, hf_lmp_db, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1168 offset += 2;
1169 } else {
1170 DISSECTOR_ASSERT(len == 13);
1171 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 11);
1172 }
1173
1174 proto_tree_add_item(tree, hf_lmp_ltaddr1, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1175 proto_tree_add_item(tree, hf_lmp_ltaddr2, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1176 offset += 1;
1177
1178 proto_tree_add_item(tree, hf_lmp_pmaddr1, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1179 offset += 1;
1180
1181 proto_tree_add_item(tree, hf_lmp_pmaddr2, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1182 offset += 1;
1183
1184 proto_tree_add_item(tree, hf_lmp_ltaddr3, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1185 proto_tree_add_item(tree, hf_lmp_ltaddr4, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1186 offset += 1;
1187
1188 proto_tree_add_item(tree, hf_lmp_pmaddr3, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1189 offset += 1;
1190
1191 proto_tree_add_item(tree, hf_lmp_pmaddr4, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1192 offset += 1;
1193
1194 proto_tree_add_item(tree, hf_lmp_ltaddr5, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1195 proto_tree_add_item(tree, hf_lmp_ltaddr6, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1196 offset += 1;
1197
1198 proto_tree_add_item(tree, hf_lmp_pmaddr5, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1199 offset += 1;
1200
1201 proto_tree_add_item(tree, hf_lmp_pmaddr6, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1202 offset += 1;
1203
1204 proto_tree_add_item(tree, hf_lmp_ltaddr7, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1205 offset += 1;
1206
1207 proto_tree_add_item(tree, hf_lmp_pmaddr7, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1208 }
1209
1210 void
dissect_incr_power_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1211 dissect_incr_power_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1212 {
1213 DISSECTOR_ASSERT(len == 2);
1214
1215 /* skipping one byte "for future use" */
1216 }
1217
1218 void
dissect_decr_power_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1219 dissect_decr_power_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1220 {
1221 DISSECTOR_ASSERT(len == 2);
1222
1223 /* skipping one byte "for future use" */
1224 }
1225
1226 void
dissect_max_power(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1227 dissect_max_power(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1228 {
1229 DISSECTOR_ASSERT(len == 1);
1230 }
1231
1232 void
dissect_min_power(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1233 dissect_min_power(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1234 {
1235 DISSECTOR_ASSERT(len == 1);
1236 }
1237
1238 void
dissect_auto_rate(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1239 dissect_auto_rate(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1240 {
1241 DISSECTOR_ASSERT(len == 1);
1242 }
1243
1244 void
dissect_preferred_rate(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1245 dissect_preferred_rate(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1246 {
1247 proto_item *rate_item;
1248 proto_tree *rate_tree;
1249
1250 DISSECTOR_ASSERT(len == 2);
1251 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1);
1252
1253 rate_item = proto_tree_add_item(tree, hf_lmp_rate, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1254 rate_tree = proto_item_add_subtree(rate_item, ett_lmp_rate);
1255
1256 proto_tree_add_item(rate_tree, hf_lmp_rate_fec, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1257 proto_tree_add_item(rate_tree, hf_lmp_rate_size, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1258 proto_tree_add_item(rate_tree, hf_lmp_rate_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1259 proto_tree_add_item(rate_tree, hf_lmp_rate_edrsize, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1260 }
1261
1262 void
dissect_version_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1263 dissect_version_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1264 {
1265 DISSECTOR_ASSERT(len == 6);
1266 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 5);
1267
1268 proto_tree_add_item(tree, hf_lmp_versnr, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1269 offset += 1;
1270
1271 proto_tree_add_item(tree, hf_lmp_compid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1272 offset += 2;
1273
1274 proto_tree_add_item(tree, hf_lmp_subversnr, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1275 }
1276
1277 void
dissect_version_res(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1278 dissect_version_res(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1279 {
1280 DISSECTOR_ASSERT(len == 6);
1281 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 5);
1282
1283 proto_tree_add_item(tree, hf_lmp_versnr, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1284 offset += 1;
1285
1286 proto_tree_add_item(tree, hf_lmp_compid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1287 offset += 2;
1288
1289 proto_tree_add_item(tree, hf_lmp_subversnr, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1290 }
1291
1292 void
dissect_features_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1293 dissect_features_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1294 {
1295 DISSECTOR_ASSERT(len == 9);
1296 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 8);
1297
1298 proto_tree_add_item(tree, hf_lmp_features, tvb, offset, 8, ENC_NA);
1299 }
1300
1301 void
dissect_features_res(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1302 dissect_features_res(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1303 {
1304 DISSECTOR_ASSERT(len == 9);
1305 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 8);
1306
1307 proto_tree_add_item(tree, hf_lmp_features, tvb, offset, 8, ENC_NA);
1308 }
1309
1310 void
dissect_quality_of_service(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1311 dissect_quality_of_service(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1312 {
1313 DISSECTOR_ASSERT(len == 4);
1314 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 3);
1315
1316 proto_tree_add_item(tree, hf_lmp_pollintvl, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1317 offset += 2;
1318
1319 proto_tree_add_item(tree, hf_lmp_nbc, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1320 }
1321
1322 void
dissect_quality_of_service_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1323 dissect_quality_of_service_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1324 {
1325 DISSECTOR_ASSERT(len == 4);
1326 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 3);
1327
1328 proto_tree_add_item(tree, hf_lmp_pollintvl, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1329 offset += 2;
1330
1331 proto_tree_add_item(tree, hf_lmp_nbc, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1332 }
1333
1334 void
dissect_sco_link_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1335 dissect_sco_link_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1336 {
1337 DISSECTOR_ASSERT(len == 7);
1338 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 6);
1339
1340 proto_tree_add_item(tree, hf_lmp_scohdl, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1341 offset += 1;
1342
1343 proto_tree_add_bitmask(tree, tvb, offset, hf_lmp_timectrl,
1344 ett_lmp_timectrl, timectrl_fields, ENC_LITTLE_ENDIAN);
1345 offset += 1;
1346
1347 proto_tree_add_item(tree, hf_lmp_dsco, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1348 offset += 1;
1349
1350 proto_tree_add_item(tree, hf_lmp_tsco, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1351 offset += 1;
1352
1353 proto_tree_add_item(tree, hf_lmp_scopkt, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1354 offset += 1;
1355
1356 proto_tree_add_item(tree, hf_lmp_airmode, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1357 }
1358
1359 void
dissect_remove_sco_link_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1360 dissect_remove_sco_link_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1361 {
1362 DISSECTOR_ASSERT(len == 3);
1363 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2);
1364
1365 proto_tree_add_item(tree, hf_lmp_scohdl, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1366 offset += 1;
1367
1368 proto_tree_add_item(tree, hf_lmp_err, tvb, offset, 1, ENC_NA);
1369 }
1370
1371 void
dissect_max_slot(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1372 dissect_max_slot(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1373 {
1374 DISSECTOR_ASSERT(len == 2);
1375 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1);
1376
1377 proto_tree_add_item(tree, hf_lmp_maxslots, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1378 }
1379
1380 void
dissect_max_slot_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1381 dissect_max_slot_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1382 {
1383 DISSECTOR_ASSERT(len == 2);
1384 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1);
1385
1386 proto_tree_add_item(tree, hf_lmp_maxslots, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1387 }
1388
1389 void
dissect_timing_accuracy_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1390 dissect_timing_accuracy_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1391 {
1392 DISSECTOR_ASSERT(len == 1);
1393 }
1394
1395 void
dissect_timing_accuracy_res(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1396 dissect_timing_accuracy_res(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1397 {
1398 DISSECTOR_ASSERT(len == 3);
1399 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2);
1400
1401 proto_tree_add_item(tree, hf_lmp_drift, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1402 offset += 1;
1403
1404 proto_tree_add_item(tree, hf_lmp_jitter, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1405 }
1406
1407 void
dissect_setup_complete(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1408 dissect_setup_complete(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1409 {
1410 DISSECTOR_ASSERT(len == 1);
1411 }
1412
1413 void
dissect_use_semi_permanent_key(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1414 dissect_use_semi_permanent_key(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1415 {
1416 DISSECTOR_ASSERT(len == 1);
1417 }
1418
1419 void
dissect_host_connection_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1420 dissect_host_connection_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1421 {
1422 DISSECTOR_ASSERT(len == 1);
1423 }
1424
1425 void
dissect_slot_offset(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1426 dissect_slot_offset(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1427 {
1428 DISSECTOR_ASSERT(len == 9);
1429 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 8);
1430
1431 proto_tree_add_item(tree, hf_lmp_slotoffset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1432 offset += 2;
1433
1434 proto_tree_add_item(tree, hf_lmp_bdaddr, tvb, offset, 6, ENC_LITTLE_ENDIAN);
1435 }
1436
1437 void
dissect_page_mode_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1438 dissect_page_mode_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1439 {
1440 DISSECTOR_ASSERT(len == 3);
1441 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2);
1442
1443 proto_tree_add_item(tree, hf_lmp_pagesch, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1444 offset += 1;
1445
1446 proto_tree_add_item(tree, hf_lmp_pssettings, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1447 }
1448
1449 void
dissect_page_scan_mode_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1450 dissect_page_scan_mode_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1451 {
1452 DISSECTOR_ASSERT(len == 3);
1453 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2);
1454
1455 proto_tree_add_item(tree, hf_lmp_pagesch, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1456 offset += 1;
1457
1458 proto_tree_add_item(tree, hf_lmp_pssettings, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1459 }
1460
1461 void
dissect_supervision_timeout(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1462 dissect_supervision_timeout(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1463 {
1464 DISSECTOR_ASSERT(len == 3);
1465 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2);
1466
1467 proto_tree_add_item(tree, hf_lmp_suptimeout, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1468 }
1469
1470 void
dissect_test_activate(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1471 dissect_test_activate(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1472 {
1473 DISSECTOR_ASSERT(len == 1);
1474 }
1475
1476 void
dissect_test_control(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1477 dissect_test_control(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1478 {
1479 DISSECTOR_ASSERT(len == 10);
1480 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 9);
1481
1482 /* FIXME these fields should all be XORed with 0x55. . . */
1483
1484 proto_tree_add_item(tree, hf_lmp_testscen, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1485 offset += 1;
1486
1487 proto_tree_add_item(tree, hf_lmp_hopmode, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1488 offset += 1;
1489
1490 proto_tree_add_item(tree, hf_lmp_txfreq, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1491 offset += 1;
1492
1493 proto_tree_add_item(tree, hf_lmp_rxfreq, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1494 offset += 1;
1495
1496 proto_tree_add_item(tree, hf_lmp_pcmode, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1497 offset += 1;
1498
1499 proto_tree_add_item(tree, hf_lmp_pollper, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1500 offset += 1;
1501
1502 proto_tree_add_item(tree, hf_lmp_pkttype, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1503 offset += 1;
1504
1505 proto_tree_add_item(tree, hf_lmp_testlen, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1506 }
1507
1508 void
dissect_encryption_key_size_mask_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1509 dissect_encryption_key_size_mask_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1510 {
1511 DISSECTOR_ASSERT(len == 1);
1512 }
1513
1514 void
dissect_encryption_key_size_mask_res(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1515 dissect_encryption_key_size_mask_res(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1516 {
1517 DISSECTOR_ASSERT(len == 3);
1518 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2);
1519
1520 proto_tree_add_item(tree, hf_lmp_ksmask, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1521 }
1522
1523 void
dissect_set_afh(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1524 dissect_set_afh(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1525 {
1526 DISSECTOR_ASSERT(len == 16);
1527 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 15);
1528
1529 proto_tree_add_item(tree, hf_lmp_afhinst, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1530 offset += 4;
1531
1532 proto_tree_add_item(tree, hf_lmp_afhmode, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1533 offset += 1;
1534
1535 proto_tree_add_item(tree, hf_lmp_afhchmap, tvb, offset, 10, ENC_NA);
1536 }
1537
1538 void
dissect_encapsulated_header(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1539 dissect_encapsulated_header(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1540 {
1541 DISSECTOR_ASSERT(len == 4);
1542 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 3);
1543
1544 proto_tree_add_item(tree, hf_lmp_encmaj, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1545 offset += 1;
1546
1547 proto_tree_add_item(tree, hf_lmp_encmin, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1548 offset += 1;
1549
1550 proto_tree_add_item(tree, hf_lmp_enclen, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1551 }
1552
1553 void
dissect_encapsulated_payload(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1554 dissect_encapsulated_payload(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1555 {
1556 DISSECTOR_ASSERT(len == 17);
1557 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16);
1558
1559 proto_tree_add_item(tree, hf_lmp_encdata, tvb, offset, 16, ENC_NA);
1560 }
1561
1562 void
dissect_simple_pairing_confirm(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1563 dissect_simple_pairing_confirm(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1564 {
1565 DISSECTOR_ASSERT(len == 17);
1566 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16);
1567
1568 proto_tree_add_item(tree, hf_lmp_commit, tvb, offset, 16, ENC_NA);
1569 }
1570
1571 void
dissect_simple_pairing_number(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1572 dissect_simple_pairing_number(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1573 {
1574 DISSECTOR_ASSERT(len == 17);
1575 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16);
1576
1577 proto_tree_add_item(tree, hf_lmp_nonce, tvb, offset, 16, ENC_NA);
1578 }
1579
1580 void
dissect_dhkey_check(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1581 dissect_dhkey_check(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1582 {
1583 DISSECTOR_ASSERT(len == 17);
1584 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 16);
1585
1586 proto_tree_add_item(tree, hf_lmp_confirm, tvb, offset, 16, ENC_NA);
1587 }
1588
1589 /* LMP PDUs with extended opcodes */
1590
1591 void
dissect_accepted_ext(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1592 dissect_accepted_ext(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1593 {
1594 DISSECTOR_ASSERT(len == 4);
1595 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2);
1596
1597 proto_tree_add_item(tree, hf_lmp_opinre, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1598 offset += 1;
1599
1600 proto_tree_add_item(tree, hf_lmp_eopinre, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1601 }
1602
1603 void
dissect_not_accepted_ext(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1604 dissect_not_accepted_ext(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1605 {
1606 DISSECTOR_ASSERT(len == 4);
1607 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2);
1608
1609 proto_tree_add_item(tree, hf_lmp_opinre, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1610 offset += 1;
1611
1612 proto_tree_add_item(tree, hf_lmp_eopinre, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1613 offset += 1;
1614
1615 proto_tree_add_item(tree, hf_lmp_err, tvb, offset, 1, ENC_NA);
1616 }
1617
1618 void
dissect_features_req_ext(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1619 dissect_features_req_ext(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1620 {
1621 DISSECTOR_ASSERT(len == 12);
1622 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 10);
1623
1624 proto_tree_add_item(tree, hf_lmp_fpage, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1625 offset += 1;
1626
1627 proto_tree_add_item(tree, hf_lmp_maxsp, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1628 offset += 1;
1629
1630 /*
1631 * extended features might need to be different from hf_lmp_features
1632 * if hf_lmp_features is broken out
1633 */
1634 proto_tree_add_item(tree, hf_lmp_features, tvb, offset, 8, ENC_NA);
1635 }
1636
1637 void
dissect_features_res_ext(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1638 dissect_features_res_ext(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1639 {
1640 DISSECTOR_ASSERT(len == 12);
1641 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 10);
1642
1643 proto_tree_add_item(tree, hf_lmp_fpage, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1644 offset += 1;
1645
1646 proto_tree_add_item(tree, hf_lmp_maxsp, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1647 offset += 1;
1648
1649 /*
1650 * extended features might need to be different from hf_lmp_features
1651 * if hf_lmp_features is broken out
1652 */
1653 proto_tree_add_item(tree, hf_lmp_features, tvb, offset, 8, ENC_NA);
1654 }
1655
1656 void
dissect_packet_type_table_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1657 dissect_packet_type_table_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1658 {
1659 DISSECTOR_ASSERT(len == 3);
1660 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1);
1661
1662 proto_tree_add_item(tree, hf_lmp_pkttypetbl, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1663 }
1664
1665 void
dissect_esco_link_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1666 dissect_esco_link_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1667 {
1668 DISSECTOR_ASSERT(len == 16);
1669 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 14);
1670
1671 proto_tree_add_item(tree, hf_lmp_escohdl, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1672 offset += 1;
1673
1674 proto_tree_add_item(tree, hf_lmp_escoltaddr, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1675 offset += 1;
1676
1677 proto_tree_add_bitmask(tree, tvb, offset, hf_lmp_timectrl,
1678 ett_lmp_timectrl, timectrl_fields, ENC_LITTLE_ENDIAN);
1679 offset += 1;
1680
1681 proto_tree_add_item(tree, hf_lmp_desco, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1682 offset += 1;
1683
1684 proto_tree_add_item(tree, hf_lmp_tesco, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1685 offset += 1;
1686
1687 proto_tree_add_item(tree, hf_lmp_wesco, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1688 offset += 1;
1689
1690 proto_tree_add_item(tree, hf_lmp_escotypems, tvb, offset, 1, ENC_NA);
1691 offset += 1;
1692
1693 proto_tree_add_item(tree, hf_lmp_escotypesm, tvb, offset, 1, ENC_NA);
1694 offset += 1;
1695
1696 proto_tree_add_item(tree, hf_lmp_escolenms, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1697 offset += 2;
1698
1699 proto_tree_add_item(tree, hf_lmp_escolensm, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1700 offset += 2;
1701
1702 proto_tree_add_item(tree, hf_lmp_airmode, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1703 offset += 1;
1704
1705 proto_tree_add_item(tree, hf_lmp_negstate, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1706 }
1707
1708 void
dissect_remove_esco_link_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1709 dissect_remove_esco_link_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1710 {
1711 DISSECTOR_ASSERT(len == 4);
1712 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 2);
1713
1714 proto_tree_add_item(tree, hf_lmp_escohdl, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1715 offset += 1;
1716
1717 proto_tree_add_item(tree, hf_lmp_err, tvb, offset, 1, ENC_NA);
1718 }
1719
1720 void
dissect_channel_classification_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1721 dissect_channel_classification_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1722 {
1723 DISSECTOR_ASSERT(len == 7);
1724 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 5);
1725
1726 proto_tree_add_item(tree, hf_lmp_afhrptmode, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1727 offset += 1;
1728
1729 proto_tree_add_item(tree, hf_lmp_afhminintvl, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1730 offset += 2;
1731
1732 proto_tree_add_item(tree, hf_lmp_afhmaxintvl, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1733 }
1734
1735 void
dissect_channel_classification(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1736 dissect_channel_classification(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1737 {
1738 DISSECTOR_ASSERT(len == 12);
1739 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 10);
1740
1741 proto_tree_add_item(tree, hf_lmp_afhclass, tvb, offset, 10, ENC_NA);
1742 }
1743
1744 void
dissect_sniff_subrating_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1745 dissect_sniff_subrating_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1746 {
1747 DISSECTOR_ASSERT(len == 9);
1748 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 7);
1749
1750 proto_tree_add_item(tree, hf_lmp_maxss, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1751 offset += 1;
1752
1753 proto_tree_add_item(tree, hf_lmp_minsmt, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1754 offset += 2;
1755
1756 proto_tree_add_item(tree, hf_lmp_sniffsi, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1757 }
1758
1759 void
dissect_sniff_subrating_res(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1760 dissect_sniff_subrating_res(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1761 {
1762 DISSECTOR_ASSERT(len == 9);
1763 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 7);
1764
1765 proto_tree_add_item(tree, hf_lmp_maxss, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1766 offset += 1;
1767
1768 proto_tree_add_item(tree, hf_lmp_minsmt, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1769 offset += 2;
1770
1771 proto_tree_add_item(tree, hf_lmp_sniffsi, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1772 }
1773
1774 void
dissect_pause_encryption_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1775 dissect_pause_encryption_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1776 {
1777 DISSECTOR_ASSERT(len == 2);
1778 }
1779
1780 void
dissect_resume_encryption_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1781 dissect_resume_encryption_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1782 {
1783 DISSECTOR_ASSERT(len == 2);
1784 }
1785
1786 void
dissect_io_capability_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1787 dissect_io_capability_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1788 {
1789 DISSECTOR_ASSERT(len == 5);
1790 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 3);
1791
1792 proto_tree_add_item(tree, hf_lmp_iocaps, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1793 offset += 1;
1794
1795 proto_tree_add_item(tree, hf_lmp_oobauthdata, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1796 offset += 1;
1797
1798 proto_tree_add_item(tree, hf_lmp_authreqs, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1799 }
1800
1801 void
dissect_io_capability_res(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1802 dissect_io_capability_res(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1803 {
1804 DISSECTOR_ASSERT(len == 5);
1805 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 3);
1806
1807 proto_tree_add_item(tree, hf_lmp_iocaps, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1808 offset += 1;
1809
1810 proto_tree_add_item(tree, hf_lmp_oobauthdata, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1811 offset += 1;
1812
1813 proto_tree_add_item(tree, hf_lmp_authreqs, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1814 }
1815
1816 void
dissect_numeric_comparison_failed(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1817 dissect_numeric_comparison_failed(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1818 {
1819 DISSECTOR_ASSERT(len == 2);
1820 }
1821
1822 void
dissect_passkey_failed(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1823 dissect_passkey_failed(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1824 {
1825 DISSECTOR_ASSERT(len == 2);
1826 }
1827
1828 void
dissect_oob_failed(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1829 dissect_oob_failed(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1830 {
1831 DISSECTOR_ASSERT(len == 2);
1832 }
1833
1834 void
dissect_keypress_notification(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1835 dissect_keypress_notification(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1836 {
1837 DISSECTOR_ASSERT(len == 3);
1838 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1);
1839
1840 proto_tree_add_item(tree, hf_lmp_nottype, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1841 }
1842
1843 void
dissect_power_control_req(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1844 dissect_power_control_req(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1845 {
1846 DISSECTOR_ASSERT(len == 3);
1847 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1);
1848
1849 proto_tree_add_item(tree, hf_lmp_pwradjreq, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1850 }
1851
1852 void
dissect_power_control_res(proto_tree * tree,tvbuff_t * tvb,int offset,int len)1853 dissect_power_control_res(proto_tree *tree, tvbuff_t *tvb, int offset, int len)
1854 {
1855 proto_item *pa_item;
1856 proto_tree *pa_tree;
1857
1858 DISSECTOR_ASSERT(len == 3);
1859 DISSECTOR_ASSERT(tvb_length_remaining(tvb, offset) >= 1);
1860
1861 pa_item = proto_tree_add_item(tree, hf_lmp_pwradjres, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1862 pa_tree = proto_item_add_subtree(pa_item, ett_lmp_pwradjres);
1863
1864 proto_tree_add_item(pa_tree, hf_lmp_pwradj_gfsk, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1865 proto_tree_add_item(pa_tree, hf_lmp_pwradj_dqpsk, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1866 proto_tree_add_item(pa_tree, hf_lmp_pwradj_8dpsk, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1867 }
1868
1869 /* Link Manager Protocol */
1870 static void
dissect_btbrlmp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree)1871 dissect_btbrlmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1872 {
1873 proto_item *lmp_item;
1874 proto_tree *lmp_tree;
1875 int offset;
1876 int len;
1877 int op; /* opcode */
1878 int eop; /* extended opcode */
1879
1880 offset = 0;
1881 len = tvb_length(tvb);
1882
1883 DISSECTOR_ASSERT(len >= 1);
1884
1885 /* make entries in protocol column and info column on summary display */
1886 col_set_str(pinfo->cinfo, COL_PROTOCOL, "LMP");
1887
1888 /* clear the info column first just in case of type fetching failure. */
1889 col_clear(pinfo->cinfo, COL_INFO);
1890
1891 op = tvb_get_guint8(tvb, offset) >> 1;
1892
1893 if (op == LMP_ESCAPE_4) {
1894 DISSECTOR_ASSERT(len >= 2);
1895
1896 eop = tvb_get_guint8(tvb, offset + 1);
1897
1898 col_add_str(pinfo->cinfo, COL_INFO, val_to_str(eop,
1899 opcode, "Unknown Extended Opcode (%d)"));
1900 } else {
1901 col_add_str(pinfo->cinfo, COL_INFO, val_to_str(op,
1902 opcode, "Unknown Opcode (%d)"));
1903 }
1904
1905 /* see if we are being asked for details */
1906 if (!tree)
1907 return;
1908
1909 lmp_item = proto_tree_add_item(tree, proto_btbrlmp, tvb, offset, -1, ENC_NA);
1910 lmp_tree = proto_item_add_subtree(lmp_item, ett_lmp);
1911
1912 proto_tree_add_item(lmp_tree, hf_lmp_tid, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1913
1914 proto_tree_add_item(lmp_tree, hf_lmp_op, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1915 offset += 1;
1916
1917 switch (op) {
1918 case LMP_NAME_REQ:
1919 dissect_name_req(lmp_tree, tvb, offset, len);
1920 break;
1921 case LMP_NAME_RES:
1922 dissect_name_res(lmp_tree, tvb, offset, len);
1923 break;
1924 case LMP_ACCEPTED:
1925 dissect_accepted(lmp_tree, tvb, offset, len);
1926 break;
1927 case LMP_NOT_ACCEPTED:
1928 dissect_not_accepted(lmp_tree, tvb, offset, len);
1929 break;
1930 case LMP_CLKOFFSET_REQ:
1931 dissect_clkoffset_req(lmp_tree, tvb, offset, len);
1932 break;
1933 case LMP_CLKOFFSET_RES:
1934 dissect_clkoffset_res(lmp_tree, tvb, offset, len);
1935 break;
1936 case LMP_DETACH:
1937 dissect_detach(lmp_tree, tvb, offset, len);
1938 break;
1939 case LMP_IN_RAND:
1940 dissect_in_rand(lmp_tree, tvb, offset, len);
1941 break;
1942 case LMP_COMB_KEY:
1943 dissect_comb_key(lmp_tree, tvb, offset, len);
1944 break;
1945 case LMP_UNIT_KEY:
1946 dissect_unit_key(lmp_tree, tvb, offset, len);
1947 break;
1948 case LMP_AU_RAND:
1949 dissect_au_rand(lmp_tree, tvb, offset, len);
1950 break;
1951 case LMP_SRES:
1952 dissect_sres(lmp_tree, tvb, offset, len);
1953 break;
1954 case LMP_TEMP_RAND:
1955 dissect_temp_rand(lmp_tree, tvb, offset, len);
1956 break;
1957 case LMP_TEMP_KEY:
1958 dissect_temp_key(lmp_tree, tvb, offset, len);
1959 break;
1960 case LMP_ENCRYPTION_MODE_REQ:
1961 dissect_encryption_mode_req(lmp_tree, tvb, offset, len);
1962 break;
1963 case LMP_ENCRYPTION_KEY_SIZE_REQ:
1964 dissect_encryption_key_size_req(lmp_tree, tvb, offset, len);
1965 break;
1966 case LMP_START_ENCRYPTION_REQ:
1967 dissect_start_encryption_req(lmp_tree, tvb, offset, len);
1968 break;
1969 case LMP_STOP_ENCRYPTION_REQ:
1970 dissect_stop_encryption_req(lmp_tree, tvb, offset, len);
1971 break;
1972 case LMP_SWITCH_REQ:
1973 dissect_switch_req(lmp_tree, tvb, offset, len);
1974 break;
1975 case LMP_HOLD:
1976 dissect_hold(lmp_tree, tvb, offset, len);
1977 break;
1978 case LMP_HOLD_REQ:
1979 dissect_hold_req(lmp_tree, tvb, offset, len);
1980 break;
1981 case LMP_SNIFF_REQ:
1982 dissect_sniff_req(lmp_tree, tvb, offset, len);
1983 break;
1984 case LMP_UNSNIFF_REQ:
1985 dissect_unsniff_req(lmp_tree, tvb, offset, len);
1986 break;
1987 case LMP_PARK_REQ:
1988 dissect_park_req(lmp_tree, tvb, offset, len);
1989 break;
1990 case LMP_SET_BROADCAST_SCAN_WINDOW:
1991 dissect_set_broadcast_scan_window(lmp_tree, tvb, offset, len);
1992 break;
1993 case LMP_MODIFY_BEACON:
1994 dissect_modify_beacon(lmp_tree, tvb, offset, len);
1995 break;
1996 case LMP_UNPARK_BD_ADDR_REQ:
1997 dissect_unpark_bd_addr_req(lmp_tree, tvb, offset, len);
1998 break;
1999 case LMP_UNPARK_PM_ADDR_REQ:
2000 dissect_unpark_pm_addr_req(lmp_tree, tvb, offset, len);
2001 break;
2002 case LMP_INCR_POWER_REQ:
2003 dissect_incr_power_req(lmp_tree, tvb, offset, len);
2004 break;
2005 case LMP_DECR_POWER_REQ:
2006 dissect_decr_power_req(lmp_tree, tvb, offset, len);
2007 break;
2008 case LMP_MAX_POWER:
2009 dissect_max_power(lmp_tree, tvb, offset, len);
2010 break;
2011 case LMP_MIN_POWER:
2012 dissect_min_power(lmp_tree, tvb, offset, len);
2013 break;
2014 case LMP_AUTO_RATE:
2015 dissect_auto_rate(lmp_tree, tvb, offset, len);
2016 break;
2017 case LMP_PREFERRED_RATE:
2018 dissect_preferred_rate(lmp_tree, tvb, offset, len);
2019 break;
2020 case LMP_VERSION_REQ:
2021 dissect_version_req(lmp_tree, tvb, offset, len);
2022 break;
2023 case LMP_VERSION_RES:
2024 dissect_version_res(lmp_tree, tvb, offset, len);
2025 break;
2026 case LMP_FEATURES_REQ:
2027 dissect_features_req(lmp_tree, tvb, offset, len);
2028 break;
2029 case LMP_FEATURES_RES:
2030 dissect_features_res(lmp_tree, tvb, offset, len);
2031 break;
2032 case LMP_QUALITY_OF_SERVICE:
2033 dissect_quality_of_service(lmp_tree, tvb, offset, len);
2034 break;
2035 case LMP_QUALITY_OF_SERVICE_REQ:
2036 dissect_quality_of_service_req(lmp_tree, tvb, offset, len);
2037 break;
2038 case LMP_SCO_LINK_REQ:
2039 dissect_sco_link_req(lmp_tree, tvb, offset, len);
2040 break;
2041 case LMP_REMOVE_SCO_LINK_REQ:
2042 dissect_remove_sco_link_req(lmp_tree, tvb, offset, len);
2043 break;
2044 case LMP_MAX_SLOT:
2045 dissect_max_slot(lmp_tree, tvb, offset, len);
2046 break;
2047 case LMP_MAX_SLOT_REQ:
2048 dissect_max_slot_req(lmp_tree, tvb, offset, len);
2049 break;
2050 case LMP_TIMING_ACCURACY_REQ:
2051 dissect_timing_accuracy_req(lmp_tree, tvb, offset, len);
2052 break;
2053 case LMP_TIMING_ACCURACY_RES:
2054 dissect_timing_accuracy_res(lmp_tree, tvb, offset, len);
2055 break;
2056 case LMP_SETUP_COMPLETE:
2057 dissect_setup_complete(lmp_tree, tvb, offset, len);
2058 break;
2059 case LMP_USE_SEMI_PERMANENT_KEY:
2060 dissect_use_semi_permanent_key(lmp_tree, tvb, offset, len);
2061 break;
2062 case LMP_HOST_CONNECTION_REQ:
2063 dissect_host_connection_req(lmp_tree, tvb, offset, len);
2064 break;
2065 case LMP_SLOT_OFFSET:
2066 dissect_slot_offset(lmp_tree, tvb, offset, len);
2067 break;
2068 case LMP_PAGE_MODE_REQ:
2069 dissect_page_mode_req(lmp_tree, tvb, offset, len);
2070 break;
2071 case LMP_PAGE_SCAN_MODE_REQ:
2072 dissect_page_scan_mode_req(lmp_tree, tvb, offset, len);
2073 break;
2074 case LMP_SUPERVISION_TIMEOUT:
2075 dissect_supervision_timeout(lmp_tree, tvb, offset, len);
2076 break;
2077 case LMP_TEST_ACTIVATE:
2078 dissect_test_activate(lmp_tree, tvb, offset, len);
2079 break;
2080 case LMP_TEST_CONTROL:
2081 dissect_test_control(lmp_tree, tvb, offset, len);
2082 break;
2083 case LMP_ENCRYPTION_KEY_SIZE_MASK_REQ:
2084 dissect_encryption_key_size_mask_req(lmp_tree, tvb, offset, len);
2085 break;
2086 case LMP_ENCRYPTION_KEY_SIZE_MASK_RES:
2087 dissect_encryption_key_size_mask_res(lmp_tree, tvb, offset, len);
2088 break;
2089 case LMP_SET_AFH:
2090 dissect_set_afh(lmp_tree, tvb, offset, len);
2091 break;
2092 case LMP_ENCAPSULATED_HEADER:
2093 dissect_encapsulated_header(lmp_tree, tvb, offset, len);
2094 break;
2095 case LMP_ENCAPSULATED_PAYLOAD:
2096 dissect_encapsulated_payload(lmp_tree, tvb, offset, len);
2097 break;
2098 case LMP_SIMPLE_PAIRING_CONFIRM:
2099 dissect_simple_pairing_confirm(lmp_tree, tvb, offset, len);
2100 break;
2101 case LMP_SIMPLE_PAIRING_NUMBER:
2102 dissect_simple_pairing_number(lmp_tree, tvb, offset, len);
2103 break;
2104 case LMP_DHKEY_CHECK:
2105 dissect_dhkey_check(lmp_tree, tvb, offset, len);
2106 break;
2107 case LMP_ESCAPE_1:
2108 break;
2109 case LMP_ESCAPE_2:
2110 break;
2111 case LMP_ESCAPE_3:
2112 break;
2113 case LMP_ESCAPE_4:
2114 /* extended opcode */
2115 DISSECTOR_ASSERT(len >= 2);
2116 proto_tree_add_item(lmp_tree, hf_lmp_eop, tvb, offset, 1, ENC_NA);
2117 offset += 1;
2118
2119 switch (eop) {
2120 case LMP_ACCEPTED_EXT:
2121 dissect_accepted_ext(lmp_tree, tvb, offset, len);
2122 break;
2123 case LMP_NOT_ACCEPTED_EXT:
2124 dissect_not_accepted_ext(lmp_tree, tvb, offset, len);
2125 break;
2126 case LMP_FEATURES_REQ_EXT:
2127 dissect_features_req_ext(lmp_tree, tvb, offset, len);
2128 break;
2129 case LMP_FEATURES_RES_EXT:
2130 dissect_features_res_ext(lmp_tree, tvb, offset, len);
2131 break;
2132 case LMP_PACKET_TYPE_TABLE_REQ:
2133 dissect_packet_type_table_req(lmp_tree, tvb, offset, len);
2134 break;
2135 case LMP_ESCO_LINK_REQ:
2136 dissect_esco_link_req(lmp_tree, tvb, offset, len);
2137 break;
2138 case LMP_REMOVE_ESCO_LINK_REQ:
2139 dissect_remove_esco_link_req(lmp_tree, tvb, offset, len);
2140 break;
2141 case LMP_CHANNEL_CLASSIFICATION_REQ:
2142 dissect_channel_classification_req(lmp_tree, tvb, offset, len);
2143 break;
2144 case LMP_CHANNEL_CLASSIFICATION:
2145 dissect_channel_classification(lmp_tree, tvb, offset, len);
2146 break;
2147 case LMP_SNIFF_SUBRATING_REQ:
2148 dissect_sniff_subrating_req(lmp_tree, tvb, offset, len);
2149 break;
2150 case LMP_SNIFF_SUBRATING_RES:
2151 dissect_sniff_subrating_res(lmp_tree, tvb, offset, len);
2152 break;
2153 case LMP_PAUSE_ENCRYPTION_REQ:
2154 dissect_pause_encryption_req(lmp_tree, tvb, offset, len);
2155 break;
2156 case LMP_RESUME_ENCRYPTION_REQ:
2157 dissect_resume_encryption_req(lmp_tree, tvb, offset, len);
2158 break;
2159 case LMP_IO_CAPABILITY_REQ:
2160 dissect_io_capability_req(lmp_tree, tvb, offset, len);
2161 break;
2162 case LMP_IO_CAPABILITY_RES:
2163 dissect_io_capability_res(lmp_tree, tvb, offset, len);
2164 break;
2165 case LMP_NUMERIC_COMPARISON_FAILED:
2166 dissect_numeric_comparison_failed(lmp_tree, tvb, offset, len);
2167 break;
2168 case LMP_PASSKEY_FAILED:
2169 dissect_passkey_failed(lmp_tree, tvb, offset, len);
2170 break;
2171 case LMP_OOB_FAILED:
2172 dissect_oob_failed(lmp_tree, tvb, offset, len);
2173 break;
2174 case LMP_KEYPRESS_NOTIFICATION:
2175 dissect_keypress_notification(lmp_tree, tvb, offset, len);
2176 break;
2177 case LMP_POWER_CONTROL_REQ:
2178 dissect_power_control_req(lmp_tree, tvb, offset, len);
2179 break;
2180 case LMP_POWER_CONTROL_RES:
2181 dissect_power_control_res(lmp_tree, tvb, offset, len);
2182 break;
2183 default:
2184 break;
2185 }
2186 default:
2187 break;
2188 }
2189 };
2190
2191 /* register the protocol with Wireshark */
2192 void
proto_register_btbrlmp(void)2193 proto_register_btbrlmp(void)
2194 {
2195
2196 /* list of fields */
2197 static hf_register_info hf[] = {
2198 { &hf_lmp_accscheme,
2199 { "Access Scheme", "btbrlmp.accscheme",
2200 FT_UINT8, BASE_DEC, VALS(access_scheme), 0xf0,
2201 NULL, HFILL }
2202 },
2203 { &hf_lmp_afhchmap,
2204 { "AFH Channel Map", "btbrlmp.afhchmap",
2205 /* could break out individual channels but long */
2206 FT_BYTES, BASE_NONE, NULL, 0x0,
2207 "Adaptive Frequency Hopping Channel Map", HFILL }
2208 },
2209 { &hf_lmp_afhclass,
2210 { "AFH Channel Classification", "btbrlmp.afhclass",
2211 /* could break out individual channels but long */
2212 FT_BYTES, BASE_NONE, NULL, 0x0,
2213 "Adaptive Frequency Hopping Channel Classification", HFILL }
2214 },
2215 { &hf_lmp_afhinst,
2216 { "AFH Instant", "btbrlmp.afhinst",
2217 FT_UINT32, BASE_HEX, NULL, 0x0,
2218 "Adaptive Frequency Hopping Instant (slot)", HFILL }
2219 },
2220 { &hf_lmp_afhmaxintvl,
2221 { "AFH Max Interval", "btbrlmp.maxintvl",
2222 FT_UINT16, BASE_HEX, NULL, 0x0,
2223 "Adaptive Maximum Interval in slots", HFILL }
2224 },
2225 { &hf_lmp_afhminintvl,
2226 { "AFH Min Interval", "btbrlmp.minintvl",
2227 FT_UINT16, BASE_HEX, NULL, 0x0,
2228 "Adaptive Minimum Interval in slots", HFILL }
2229 },
2230 { &hf_lmp_afhmode,
2231 { "AFH Mode", "btbrlmp.afhmode",
2232 FT_UINT8, BASE_DEC, VALS(afh_mode), 0x0,
2233 "Adaptive Frequency Hopping Mode", HFILL }
2234 },
2235 { &hf_lmp_afhrptmode,
2236 { "AFH Reporting Mode", "btbrlmp.afhrptmode",
2237 FT_UINT8, BASE_DEC, VALS(afh_reporting_mode), 0x0,
2238 "Adaptive Frequency Hopping Reporting Mode", HFILL }
2239 },
2240 { &hf_lmp_airmode,
2241 { "Air Mode", "btbrlmp.airmode",
2242 FT_UINT8, BASE_HEX, VALS(air_mode), 0x0,
2243 NULL, HFILL }
2244 },
2245 { &hf_lmp_araddr,
2246 { "AR_ADDR", "btbrlmp.araddr",
2247 FT_UINT8, BASE_HEX, NULL, 0xfe,
2248 NULL, HFILL }
2249 },
2250 { &hf_lmp_authreqs,
2251 { "Authentication Requirements", "btbrlmp.authreqs",
2252 FT_UINT8, BASE_HEX, VALS(auth_requirements), 0xf0,
2253 NULL, HFILL }
2254 },
2255 { &hf_lmp_authres,
2256 { "Authentication Response", "btbrlmp.authres",
2257 FT_BYTES, BASE_NONE, NULL, 0x0,
2258 NULL, HFILL }
2259 },
2260 { &hf_lmp_bdaddr,
2261 { "BD_ADDR", "btbrlmp.bdaddr",
2262 FT_UINT64, BASE_HEX, NULL, 0x0000ffffffffffff,
2263 NULL, HFILL }
2264 },
2265 { &hf_lmp_bdaddr1,
2266 { "BD_ADDR 1", "btbrlmp.bdaddr",
2267 FT_UINT64, BASE_HEX, NULL, 0x0000ffffffffffff,
2268 NULL, HFILL }
2269 },
2270 { &hf_lmp_bdaddr2,
2271 { "BD_ADDR2", "btbrlmp.bdaddr",
2272 FT_UINT64, BASE_HEX, NULL, 0x0000ffffffffffff,
2273 "BD_ADDR 2", HFILL }
2274 },
2275 { &hf_lmp_bsw,
2276 { "Broadcast Scan Window", "btbrlmp.bsw",
2277 FT_UINT16, BASE_HEX, NULL, 0x0,
2278 "Broadcast Scan Window in slots", HFILL }
2279 },
2280 { &hf_lmp_clkoffset,
2281 { "Clock Offset", "btbrlmp.clkoffset",
2282 FT_UINT16, BASE_DEC, NULL, 0x0,
2283 "Clock Offset in units of 1.25 ms", HFILL }
2284 },
2285 { &hf_lmp_commit,
2286 { "Commitment Value", "btbrlmp.commit",
2287 FT_BYTES, BASE_NONE, NULL, 0x0,
2288 NULL, HFILL }
2289 },
2290 { &hf_lmp_confirm,
2291 { "Confirmation Value", "btbrlmp.confirm",
2292 FT_BYTES, BASE_NONE, NULL, 0x0,
2293 NULL, HFILL }
2294 },
2295 { &hf_lmp_compid,
2296 { "Company ID", "btbrlmp.compid",
2297 FT_UINT16, BASE_DEC, VALS(compid), 0x0,
2298 NULL, HFILL }
2299 },
2300 { &hf_lmp_cryptmode,
2301 { "Encryption Mode", "btbrlmp.cryptmode",
2302 FT_UINT8, BASE_DEC, VALS(encryption_mode), 0x0,
2303 NULL, HFILL }
2304 },
2305 { &hf_lmp_daccess,
2306 { "Daccess", "btbrlmp.daccess",
2307 FT_UINT8, BASE_HEX, NULL, 0x0,
2308 "Daccess in slots", HFILL }
2309 },
2310 { &hf_lmp_db,
2311 { "Db", "btbrlmp.db",
2312 FT_UINT16, BASE_HEX, NULL, 0x0,
2313 "Db in slots", HFILL }
2314 },
2315 { &hf_lmp_dbsleep,
2316 { "Dbsleep", "btbrlmp.dbsleep",
2317 FT_UINT8, BASE_HEX, NULL, 0x0,
2318 NULL, HFILL }
2319 },
2320 { &hf_lmp_deltab,
2321 { "Deltab", "btbrlmp.deltab",
2322 FT_UINT8, BASE_HEX, NULL, 0x0,
2323 "Deltab in slots", HFILL }
2324 },
2325 { &hf_lmp_desco,
2326 { "Desco", "btbrlmp.desco",
2327 FT_UINT8, BASE_HEX, NULL, 0x0,
2328 "Desco in slots", HFILL }
2329 },
2330 { &hf_lmp_drift,
2331 { "Drift", "btbrlmp.drift",
2332 FT_UINT8, BASE_DEC, NULL, 0x0,
2333 "Drift in ppm", HFILL }
2334 },
2335 { &hf_lmp_dsco,
2336 { "Dsco", "btbrlmp.dsco",
2337 FT_UINT8, BASE_HEX, NULL, 0x0,
2338 "Dsco in slots", HFILL }
2339 },
2340 { &hf_lmp_dsniff,
2341 { "Dsniff", "btbrlmp.dsniff",
2342 FT_UINT16, BASE_HEX, NULL, 0x0,
2343 "Dsniff in slots", HFILL }
2344 },
2345 { &hf_lmp_encdata,
2346 { "Encapsulated Data", "btbrlmp.encdata",
2347 FT_BYTES, BASE_NONE, NULL, 0x0,
2348 NULL, HFILL }
2349 },
2350 { &hf_lmp_enclen,
2351 { "Encapsulated Length", "btbrlmp.enclen",
2352 FT_UINT8, BASE_DEC, NULL, 0x0,
2353 NULL, HFILL }
2354 },
2355 { &hf_lmp_encmaj,
2356 { "Encapsulated Major Type", "btbrlmp.encmaj",
2357 FT_UINT8, BASE_DEC, NULL, 0x0,
2358 NULL, HFILL }
2359 },
2360 { &hf_lmp_encmin,
2361 { "Encapsulated Minor Type", "btbrlmp.encmin",
2362 FT_UINT8, BASE_DEC, NULL, 0x0,
2363 NULL, HFILL }
2364 },
2365 { &hf_lmp_eop,
2366 { "Extended Opcode", "btbrlmp.eop",
2367 FT_UINT8, BASE_DEC, VALS(ext_opcode), 0x0,
2368 NULL, HFILL }
2369 },
2370 { &hf_lmp_eopinre,
2371 { "In Response To", "btbrlmp.eopinre",
2372 FT_UINT8, BASE_DEC, VALS(ext_opcode), 0x0,
2373 "Extended Opcode this is in response to", HFILL }
2374 },
2375 { &hf_lmp_escolenms,
2376 { "Packet Length M -> S", "btbrlmp.escolenms",
2377 FT_UINT16, BASE_DEC, NULL, 0x0,
2378 "Packet Length in bytes Master to Slave", HFILL }
2379 },
2380 { &hf_lmp_escolensm,
2381 { "Packet Length S -> M", "btbrlmp.escolensm",
2382 FT_UINT16, BASE_DEC, NULL, 0x0,
2383 "Packet Length in bytes Slave to Master", HFILL }
2384 },
2385 { &hf_lmp_escotypems,
2386 { "eSCO Packet Type M -> S", "btbrlmp.escotypems",
2387 FT_UINT8, BASE_HEX, VALS(esco_packet_type), 0x0,
2388 "eSCO Packet Type Master to Slave", HFILL }
2389 },
2390 { &hf_lmp_escotypesm,
2391 { "eSCO Packet Type S -> M", "btbrlmp.escotypesm",
2392 FT_UINT8, BASE_HEX, VALS(esco_packet_type), 0x0,
2393 "eSCO Packet Type Slave to Master", HFILL }
2394 },
2395 { &hf_lmp_err,
2396 { "Error Code", "btbrlmp.err",
2397 FT_UINT8, BASE_HEX, VALS(error_code), 0x0,
2398 NULL, HFILL }
2399 },
2400 { &hf_lmp_escohdl,
2401 { "eSCO Handle", "btbrlmp.escohdl",
2402 FT_UINT8, BASE_HEX, NULL, 0x0,
2403 NULL, HFILL }
2404 },
2405 { &hf_lmp_escoltaddr,
2406 { "eSCO LT_ADDR", "btbrlmp.escoltaddr",
2407 FT_UINT8, BASE_HEX, NULL, 0x0,
2408 "eSCO Logical Transport Address", HFILL }
2409 },
2410 { &hf_lmp_features,
2411 { "Features", "btbrlmp.features",
2412 /* could break out individual features but long */
2413 FT_BYTES, BASE_NONE, NULL, 0x0,
2414 "Feature Mask", HFILL }
2415 },
2416 { &hf_lmp_fpage,
2417 { "Features Page", "btbrlmp.fpage",
2418 FT_UINT8, BASE_DEC, VALS(features_page), 0x0,
2419 NULL, HFILL }
2420 },
2421 { &hf_lmp_htime,
2422 { "Hold Time", "btbrlmp.htime",
2423 FT_UINT16, BASE_HEX, NULL, 0x0,
2424 "Hold Time in slots", HFILL }
2425 },
2426 { &hf_lmp_hinst,
2427 { "Hold Instant", "btbrlmp.hinst",
2428 FT_UINT32, BASE_HEX, NULL, 0x0,
2429 "Hold Instant (slot)", HFILL }
2430 },
2431 { &hf_lmp_hopmode,
2432 { "Hopping Mode", "btbrlmp.hopmode",
2433 FT_UINT8, BASE_DEC, VALS(hopping_mode), 0x0,
2434 NULL, HFILL }
2435 },
2436 { &hf_lmp_iocaps,
2437 { "IO Capabilities", "btbrlmp.iocaps",
2438 FT_UINT8, BASE_DEC, VALS(io_capabilities), 0x0,
2439 "Input/Output Capabilities", HFILL }
2440 },
2441 { &hf_lmp_jitter,
2442 { "Jitter", "btbrlmp.jitter",
2443 FT_UINT8, BASE_DEC, NULL, 0x0,
2444 "Jitter in microseconds", HFILL }
2445 },
2446 { &hf_lmp_key,
2447 { "Key", "btbrlmp.key",
2448 FT_BYTES, BASE_NONE, NULL, 0x0,
2449 NULL, HFILL }
2450 },
2451 { &hf_lmp_keysz,
2452 { "Key Size", "btbrlmp.keysz",
2453 FT_UINT8, BASE_DEC, NULL, 0x0,
2454 "Key Size in bytes", HFILL }
2455 },
2456 { &hf_lmp_ksmask,
2457 { "Key Size Mask", "btbrlmp.ksmask",
2458 FT_UINT16, BASE_HEX, NULL, 0x0,
2459 NULL, HFILL }
2460 },
2461 { &hf_lmp_ltaddr1,
2462 { "LT_ADDR 1", "btbrlmp.ltaddr",
2463 FT_UINT8, BASE_HEX, NULL, 0x0f,
2464 "Logical Transport Address 1", HFILL }
2465 },
2466 { &hf_lmp_ltaddr2,
2467 { "LT_ADDR 2", "btbrlmp.ltaddr",
2468 FT_UINT8, BASE_HEX, NULL, 0xf0,
2469 "Logical Transport Address 2", HFILL }
2470 },
2471 { &hf_lmp_ltaddr3,
2472 { "LT_ADDR 3", "btbrlmp.ltaddr",
2473 FT_UINT8, BASE_HEX, NULL, 0x0f,
2474 "Logical Transport Address 3", HFILL }
2475 },
2476 { &hf_lmp_ltaddr4,
2477 { "LT_ADDR 4", "btbrlmp.ltaddr",
2478 FT_UINT8, BASE_HEX, NULL, 0xf0,
2479 "Logical Transport Address 4", HFILL }
2480 },
2481 { &hf_lmp_ltaddr5,
2482 { "LT_ADDR 5", "btbrlmp.ltaddr",
2483 FT_UINT8, BASE_HEX, NULL, 0x0f,
2484 "Logical Transport Address 5", HFILL }
2485 },
2486 { &hf_lmp_ltaddr6,
2487 { "LT_ADDR 6", "btbrlmp.ltaddr",
2488 FT_UINT8, BASE_HEX, NULL, 0xf0,
2489 "Logical Transport Address 6", HFILL }
2490 },
2491 { &hf_lmp_ltaddr7,
2492 { "LT_ADDR 7", "btbrlmp.ltaddr",
2493 FT_UINT8, BASE_HEX, NULL, 0x0f,
2494 "Logical Transport Address 7", HFILL }
2495 },
2496 { &hf_lmp_maccess,
2497 { "Maccess", "btbrlmp.maccess",
2498 FT_UINT8, BASE_HEX, NULL, 0x0f,
2499 "Number of access windows", HFILL }
2500 },
2501 { &hf_lmp_maxslots,
2502 { "Max Slots", "btbrlmp.maxslots",
2503 FT_UINT8, BASE_HEX, NULL, 0x0,
2504 NULL, HFILL }
2505 },
2506 { &hf_lmp_maxsp,
2507 { "Max Supported Page", "btbrlmp.maxsp",
2508 FT_UINT8, BASE_DEC, NULL, 0x0,
2509 "Highest extended features page with non-zero bit", HFILL }
2510 },
2511 { &hf_lmp_maxss,
2512 { "Max Sniff Subrate", "btbrlmp.maxss",
2513 FT_UINT8, BASE_DEC, NULL, 0x0,
2514 NULL, HFILL }
2515 },
2516 { &hf_lmp_minsmt,
2517 { "Min Sniff Mode Timeout", "btbrlmp.minsmt",
2518 FT_UINT16, BASE_HEX, NULL, 0x0,
2519 "Min Sniff Mode Timeout in slots", HFILL }
2520 },
2521 { &hf_lmp_naccslots,
2522 { "Nacc-slots", "btbrlmp.naccslots",
2523 FT_UINT8, BASE_HEX, NULL, 0x0,
2524 NULL, HFILL }
2525 },
2526 { &hf_lmp_namefrag,
2527 { "Name Fragment", "btbrlmp.namefrag",
2528 FT_STRING, BASE_NONE, NULL, 0x0,
2529 NULL, HFILL }
2530 },
2531 { &hf_lmp_namelen,
2532 { "Name Length", "btbrlmp.namelen",
2533 FT_UINT8, BASE_DEC, NULL, 0x0,
2534 "Name Length in bytes", HFILL }
2535 },
2536 { &hf_lmp_nameoffset,
2537 { "Name Offset", "btbrlmp.nameoffset",
2538 FT_UINT8, BASE_DEC, NULL, 0x0,
2539 "Name Offset in bytes", HFILL }
2540 },
2541 { &hf_lmp_nb,
2542 { "Nb", "btbrlmp.nb",
2543 FT_UINT8, BASE_HEX, NULL, 0x0,
2544 NULL, HFILL }
2545 },
2546 { &hf_lmp_nbc,
2547 { "Nbc", "btbrlmp.nbc",
2548 FT_UINT8, BASE_HEX, NULL, 0x0,
2549 NULL, HFILL }
2550 },
2551 { &hf_lmp_nbsleep,
2552 { "Nbsleep", "btbrlmp.nbsleep",
2553 FT_UINT8, BASE_HEX, NULL, 0x0,
2554 NULL, HFILL }
2555 },
2556 { &hf_lmp_negstate,
2557 { "Negotiation State", "btbrlmp.negstate",
2558 FT_UINT8, BASE_DEC, VALS(negotiation_state), 0x0,
2559 NULL, HFILL }
2560 },
2561 { &hf_lmp_nonce,
2562 { "Nonce Value", "btbrlmp.nonce",
2563 FT_BYTES, BASE_NONE, NULL, 0x0,
2564 NULL, HFILL }
2565 },
2566 { &hf_lmp_nottype,
2567 { "Notification Type", "btbrlmp.nottype",
2568 FT_UINT8, BASE_DEC, VALS(notification_value), 0x0,
2569 NULL, HFILL }
2570 },
2571 { &hf_lmp_npoll,
2572 { "Npoll", "btbrlmp.npoll",
2573 FT_UINT8, BASE_HEX, NULL, 0x0,
2574 NULL, HFILL }
2575 },
2576 { &hf_lmp_oobauthdata,
2577 { "OOB Authentication Data", "btbrlmp.oobauthdata",
2578 FT_UINT8, BASE_DEC, VALS(oob_auth_data), 0xfe,
2579 NULL, HFILL }
2580 },
2581 { &hf_lmp_op,
2582 { "Opcode", "btbrlmp.op",
2583 FT_UINT8, BASE_DEC, VALS(opcode), 0xfe,
2584 NULL, HFILL }
2585 },
2586 { &hf_lmp_opinre,
2587 { "In Response To", "btbrlmp.opinre",
2588 FT_UINT8, BASE_DEC, VALS(opcode), 0x7f,
2589 "Opcode this is in response to", HFILL }
2590 },
2591 { &hf_lmp_pagesch,
2592 { "Paging Scheme", "btbrlmp.pagesch",
2593 FT_UINT8, BASE_DEC, VALS(paging_scheme), 0x0,
2594 NULL, HFILL }
2595 },
2596 { &hf_lmp_pcmode,
2597 { "Power Control Mode", "btbrlmp.pcmode",
2598 FT_UINT8, BASE_DEC, VALS(power_control_mode), 0x0,
2599 NULL, HFILL }
2600 },
2601 { &hf_lmp_pkttype,
2602 { "Packet Type", "btbrlmp.pkttype",
2603 /* FIXME break out further */
2604 FT_UINT8, BASE_HEX, NULL, 0x0,
2605 "Packet Type", HFILL }
2606 },
2607 { &hf_lmp_pkttypetbl,
2608 { "Packet Type Table", "btbrlmp.pkttypetbl",
2609 FT_UINT8, BASE_DEC, VALS(packet_type_table), 0x0,
2610 NULL, HFILL }
2611 },
2612 { &hf_lmp_pmaddr,
2613 { "PM_ADDR", "btbrlmp.pmaddr",
2614 FT_UINT8, BASE_HEX, NULL, 0x0,
2615 NULL, HFILL }
2616 },
2617 { &hf_lmp_pmaddr1,
2618 { "PM_ADDR 1", "btbrlmp.pmaddr1",
2619 FT_UINT8, BASE_HEX, NULL, 0x0,
2620 NULL, HFILL }
2621 },
2622 { &hf_lmp_pmaddr2,
2623 { "PM_ADDR 2", "btbrlmp.pmaddr2",
2624 FT_UINT8, BASE_HEX, NULL, 0x0,
2625 NULL, HFILL }
2626 },
2627 { &hf_lmp_pmaddr3,
2628 { "PM_ADDR 3", "btbrlmp.pmaddr3",
2629 FT_UINT8, BASE_HEX, NULL, 0x0,
2630 NULL, HFILL }
2631 },
2632 { &hf_lmp_pmaddr4,
2633 { "PM_ADDR 4", "btbrlmp.pmaddr4",
2634 FT_UINT8, BASE_HEX, NULL, 0x0,
2635 NULL, HFILL }
2636 },
2637 { &hf_lmp_pmaddr5,
2638 { "PM_ADDR 5", "btbrlmp.pmaddr5",
2639 FT_UINT8, BASE_HEX, NULL, 0x0,
2640 NULL, HFILL }
2641 },
2642 { &hf_lmp_pmaddr6,
2643 { "PM_ADDR 6", "btbrlmp.pmaddr6",
2644 FT_UINT8, BASE_HEX, NULL, 0x0,
2645 NULL, HFILL }
2646 },
2647 { &hf_lmp_pmaddr7,
2648 { "PM_ADDR 7", "btbrlmp.pmaddr7",
2649 FT_UINT8, BASE_HEX, NULL, 0x0,
2650 NULL, HFILL }
2651 },
2652 { &hf_lmp_pollintvl,
2653 { "Poll Interval", "btbrlmp.pollintvl",
2654 FT_UINT16, BASE_HEX, NULL, 0x0,
2655 "Poll Interval in slots", HFILL }
2656 },
2657 { &hf_lmp_pollper,
2658 { "Poll Period", "btbrlmp.pollper",
2659 FT_UINT8, BASE_DEC, NULL, 0x0,
2660 "Poll Period in units of 1.25 ms", HFILL }
2661 },
2662 { &hf_lmp_pssettings,
2663 { "Paging Scheme Settings", "btbrlmp.pssettings",
2664 FT_UINT8, BASE_DEC, VALS(paging_scheme_settings), 0x0,
2665 NULL, HFILL }
2666 },
2667 { &hf_lmp_pwradjreq,
2668 { "Power Adjustment Request", "btbrlmp.pwradjreq",
2669 FT_UINT8, BASE_DEC, VALS(power_adjust_req), 0x0,
2670 NULL, HFILL }
2671 },
2672 { &hf_lmp_pwradjres,
2673 { "Power Adjustment Response", "btbrlmp.pwradjres",
2674 FT_UINT8, BASE_HEX, NULL, 0x0,
2675 NULL, HFILL }
2676 },
2677 { &hf_lmp_pwradj_8dpsk,
2678 { "8DPSK", "btbrlmp.pwradj_8dpsk",
2679 FT_UINT8, BASE_DEC, VALS(power_adjust_res), 0x30,
2680 "8DPSK Power Adjustment Response", HFILL }
2681 },
2682 { &hf_lmp_pwradj_dqpsk,
2683 { "DQPSK", "btbrlmp.pwradj_dqpsk",
2684 FT_UINT8, BASE_DEC, VALS(power_adjust_res), 0x0C,
2685 "DQPSK Power Adjustment Response", HFILL }
2686 },
2687 { &hf_lmp_pwradj_gfsk,
2688 { "GFSK", "btbrlmp.pwradj_gfsk",
2689 FT_UINT8, BASE_DEC, VALS(power_adjust_res), 0x03,
2690 "GFSK Power Adjustment Response", HFILL }
2691 },
2692 { &hf_lmp_rand,
2693 { "Random Number", "btbrlmp.rand",
2694 FT_BYTES, BASE_NONE, NULL, 0x0,
2695 NULL, HFILL }
2696 },
2697 { &hf_lmp_rate,
2698 { "Data Rate", "btbrlmp.rate",
2699 FT_UINT8, BASE_HEX, NULL, 0x0,
2700 NULL, HFILL }
2701 },
2702 { &hf_lmp_rate_fec,
2703 { "FEC", "btbrlmp.rate.fec",
2704 FT_BOOLEAN, BASE_DEC, TFS(&fec), 0x01,
2705 "Forward Error Correction", HFILL }
2706 },
2707 { &hf_lmp_rate_size,
2708 { "Packet Size", "btbrlmp.rate.size",
2709 FT_UINT8, BASE_HEX, VALS(packet_size), 0x06,
2710 "Basic Rate Packet Size", HFILL }
2711 },
2712 { &hf_lmp_rate_type,
2713 { "EDR Type", "btbrlmp.rate.type",
2714 FT_UINT8, BASE_HEX, VALS(edr_type), 0x18,
2715 "Enhanced Data Rate type", HFILL }
2716 },
2717 { &hf_lmp_rate_edrsize,
2718 { "EDR Size", "btbrlmp.rate.edrsize",
2719 FT_UINT8, BASE_HEX, VALS(packet_size), 0x60,
2720 "Enhanced Data Rate packet size", HFILL }
2721 },
2722 { &hf_lmp_rxfreq,
2723 { "RX Frequency", "btbrlmp.rxfreq",
2724 FT_UINT8, BASE_DEC, NULL, 0x0,
2725 "Receive Frequency in MHz above 2402", HFILL }
2726 },
2727 { &hf_lmp_scohdl,
2728 { "SCO Handle", "btbrlmp.scohdl",
2729 FT_UINT8, BASE_HEX, NULL, 0x0,
2730 NULL, HFILL }
2731 },
2732 { &hf_lmp_scopkt,
2733 { "SCO Packet", "btbrlmp.scopkt",
2734 FT_UINT8, BASE_DEC, VALS(sco_packet), 0x0,
2735 NULL, HFILL }
2736 },
2737 { &hf_lmp_slotoffset,
2738 { "Slot Offset", "btbrlmp.slotoffset",
2739 FT_UINT16, BASE_DEC, NULL, 0x0,
2740 "Slot Offset in microseconds", HFILL }
2741 },
2742 { &hf_lmp_sniffatt,
2743 { "Sniff Attempt", "btbrlmp.sniffatt",
2744 FT_UINT16, BASE_HEX, NULL, 0x0,
2745 "Number of receive slots", HFILL }
2746 },
2747 { &hf_lmp_sniffsi,
2748 { "Sniff Subrating Instant", "btbrlmp.sniffsi",
2749 FT_UINT32, BASE_HEX, NULL, 0x0,
2750 "Sniff Subrating Instant (slot)", HFILL }
2751 },
2752 { &hf_lmp_sniffto,
2753 { "Sniff Timeout", "btbrlmp.sniffto",
2754 FT_UINT16, BASE_HEX, NULL, 0x0,
2755 "Number of receive slots", HFILL }
2756 },
2757 { &hf_lmp_subversnr,
2758 { "SubVersNr", "btbrlmp.subversnr",
2759 FT_UINT16, BASE_DEC, NULL, 0x0,
2760 "SubVersion", HFILL }
2761 },
2762 { &hf_lmp_suptimeout,
2763 { "Supervision Timeout", "btbrlmp.suptimeout",
2764 FT_UINT16, BASE_HEX, NULL, 0x0,
2765 "Supervision Timeout in slots", HFILL }
2766 },
2767 { &hf_lmp_swinst,
2768 { "Switch Instant", "btbrlmp.swinst",
2769 FT_UINT32, BASE_HEX, NULL, 0x0,
2770 "Switch Instant (slot)", HFILL }
2771 },
2772 { &hf_lmp_taccess,
2773 { "Taccess", "btbrlmp.taccess",
2774 FT_UINT8, BASE_HEX, NULL, 0x0,
2775 "Taccess in slots", HFILL }
2776 },
2777 { &hf_lmp_tb,
2778 { "Tb", "btbrlmp.tb",
2779 FT_UINT16, BASE_HEX, NULL, 0x0,
2780 "Tb in slots", HFILL }
2781 },
2782 { &hf_lmp_tesco,
2783 { "Tesco", "btbrlmp.tesco",
2784 FT_UINT8, BASE_HEX, NULL, 0x0,
2785 "Tesco in slots", HFILL }
2786 },
2787 { &hf_lmp_testlen,
2788 { "Test Length", "btbrlmp.testlen",
2789 FT_UINT16, BASE_DEC, NULL, 0x0,
2790 "Length of test sequence in bytes", HFILL }
2791 },
2792 { &hf_lmp_testscen,
2793 { "Test Scenario", "btbrlmp.testscen",
2794 FT_UINT8, BASE_DEC, VALS(test_scenario), 0x0,
2795 NULL, HFILL }
2796 },
2797 { &hf_lmp_tid,
2798 { "TID", "btbrlmp.tid",
2799 FT_BOOLEAN, BASE_DEC, TFS(&tid), 0x01,
2800 "Transaction ID", HFILL }
2801 },
2802 { &hf_lmp_timectrl,
2803 { "Timing Control Flags", "btbrlmp.timectrl",
2804 FT_UINT8, BASE_HEX, NULL, 0x0,
2805 NULL, HFILL }
2806 },
2807 { &hf_lmp_time_change,
2808 { "Timing Change", "btbrlmp.time.change",
2809 FT_BOOLEAN, 8, TFS(&time_change), 0x01,
2810 NULL, HFILL }
2811 },
2812 { &hf_lmp_time_init,
2813 { "Initialization", "btbrlmp.time.init",
2814 FT_BOOLEAN, 8, TFS(&time_init), 0x02,
2815 NULL, HFILL }
2816 },
2817 { &hf_lmp_time_accwin,
2818 { "Access Window", "btbrlmp.time.accwin",
2819 FT_BOOLEAN, 8, TFS(&time_accwin), 0x04,
2820 NULL, HFILL }
2821 },
2822 { &hf_lmp_tsco,
2823 { "Tsco", "btbrlmp.tsco",
2824 FT_UINT8, BASE_HEX, NULL, 0x0,
2825 "Tsco in slots", HFILL }
2826 },
2827 { &hf_lmp_tsniff,
2828 { "Tsniff", "btbrlmp.tsniff",
2829 FT_UINT16, BASE_HEX, NULL, 0x0,
2830 "Tsniff in slots", HFILL }
2831 },
2832 { &hf_lmp_txfreq,
2833 { "TX Frequency", "btbrlmp.txfreq",
2834 FT_UINT8, BASE_DEC, NULL, 0x0,
2835 "Transmit Frequency in MHz above 2402", HFILL }
2836 },
2837 { &hf_lmp_versnr,
2838 { "VersNr", "btbrlmp.versnr",
2839 FT_UINT8, BASE_DEC, VALS(versnr), 0x0,
2840 "Version", HFILL }
2841 },
2842 { &hf_lmp_wesco,
2843 { "Wesco", "btbrlmp.wesco",
2844 FT_UINT8, BASE_HEX, NULL, 0x0,
2845 "Number of slots in retransmission window", HFILL }
2846 },
2847 };
2848
2849 /* protocol subtree arrays */
2850 static gint *ett[] = {
2851 &ett_lmp,
2852 &ett_lmp_pwradjres,
2853 &ett_lmp_rate,
2854 &ett_lmp_timectrl,
2855 };
2856
2857 /* register the protocol name and description */
2858 proto_btbrlmp = proto_register_protocol(
2859 "Bluetooth BR Link Manager Protocol", /* full name */
2860 "btbrlmp", /* short name */
2861 "btbrlmp" /* abbreviation (e.g. for filters) */
2862 );
2863
2864 register_dissector("btbrlmp", dissect_btbrlmp, proto_btbrlmp);
2865
2866 /* register the header fields and subtrees used */
2867 proto_register_field_array(proto_btbrlmp, hf, array_length(hf));
2868 proto_register_subtree_array(ett, array_length(ett));
2869 }
2870
2871 void
proto_reg_handoff_btbrlmp(void)2872 proto_reg_handoff_btbrlmp(void)
2873 {
2874 }
2875
2876 /*
2877 * Editor modelines - http://www.wireshark.org/tools/modelines.html
2878 *
2879 * Local variables:
2880 * c-basic-offset: 4
2881 * tab-width: 8
2882 * indent-tabs-mode: nil
2883 * End:
2884 *
2885 * vi: set shiftwidth=4 tabstop=8 expandtab:
2886 * :indentSize=4:tabSize=8:noTabs=true:
2887 */
2888