1 /* 2 * 3 * BlueZ - Bluetooth protocol stack for Linux 4 * 5 * Copyright (C) 2004-2011 Marcel Holtmann <marcel (at) holtmann.org> 6 * 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 * 22 */ 23 24 #ifdef HAVE_CONFIG_H 25 #include <config.h> 26 #endif 27 28 #include <stdio.h> 29 #include <errno.h> 30 #include <unistd.h> 31 #include <stdlib.h> 32 #include <string.h> 33 34 #include <sys/types.h> 35 #include <netinet/in.h> 36 37 #include "parser.h" 38 39 #define CSR_U8(frm) (get_u8(frm)) 40 #define CSR_U16(frm) (btohs(htons(get_u16(frm)))) 41 #define CSR_U32(frm) ((CSR_U16(frm) << 16) + CSR_U16(frm)) 42 #define CSR_S16(frm) (btohs(htons(get_u16(frm)))) 43 44 static char *type2str(uint16_t type) 45 { 46 switch (type) { 47 case 0x0000: 48 return "Get req"; 49 case 0x0001: 50 return "Get rsp"; 51 case 0x0002: 52 return "Set req"; 53 default: 54 return "Reserved"; 55 } 56 } 57 58 static inline void valueless_dump(int level, char *str, struct frame *frm) 59 { 60 p_indent(level, frm); 61 printf("%s\n", str); 62 } 63 64 static inline void complex_dump(int level, char *str, struct frame *frm) 65 { 66 p_indent(level, frm); 67 printf("%s\n", str); 68 69 raw_dump(level, frm); 70 } 71 72 static inline void bool_dump(int level, char *str, struct frame *frm) 73 { 74 uint16_t value; 75 76 value = CSR_U16(frm); 77 78 p_indent(level, frm); 79 printf("%s: value %s (%d)\n", str, value ? "TRUE" : "FALSE", value); 80 } 81 82 static inline void int8_dump(int level, char *str, struct frame *frm) 83 { 84 int16_t value; 85 86 value = CSR_S16(frm); 87 88 p_indent(level, frm); 89 printf("%s: value %d (0x%2.2x)\n", str, value, value); 90 } 91 92 static inline void int16_dump(int level, char *str, struct frame *frm) 93 { 94 int16_t value; 95 96 value = CSR_S16(frm); 97 98 p_indent(level, frm); 99 printf("%s: value %d (0x%2.2x)\n", str, value, value); 100 } 101 102 static inline void uint16_dump(int level, char *str, struct frame *frm) 103 { 104 uint16_t value; 105 106 value = CSR_U16(frm); 107 108 p_indent(level, frm); 109 printf("%s: value %d (0x%4.4x)\n", str, value, value); 110 } 111 112 static inline void uint32_dump(int level, char *str, struct frame *frm) 113 { 114 uint32_t value; 115 116 value = CSR_U32(frm); 117 118 p_indent(level, frm); 119 printf("%s: value %d (0x%4.4x)\n", str, value, value); 120 } 121 122 static inline void bdaddr_dump(int level, char *str, struct frame *frm) 123 { 124 char addr[18]; 125 126 p_ba2str(frm->ptr, addr); 127 128 p_indent(level, frm); 129 printf("%s: bdaddr %s\n", str, addr); 130 } 131 132 static inline void features_dump(int level, char *str, struct frame *frm) 133 { 134 unsigned char features[8]; 135 int i; 136 137 memcpy(features, frm->ptr, 8); 138 139 p_indent(level, frm); 140 printf("%s: features", str); 141 for (i = 0; i < 8; i++) 142 printf(" 0x%02x", features[i]); 143 printf("\n"); 144 } 145 146 static inline void commands_dump(int level, char *str, struct frame *frm) 147 { 148 unsigned char commands[64]; 149 unsigned int i; 150 151 memcpy(commands, frm->ptr, frm->len); 152 153 p_indent(level, frm); 154 printf("%s: commands", str); 155 for (i = 0; i < frm->len; i++) 156 printf(" 0x%02x", commands[i]); 157 printf("\n"); 158 } 159 160 static inline void handle_length_dump(int level, char *str, struct frame *frm) 161 { 162 uint16_t handle, length; 163 164 handle = CSR_U16(frm); 165 length = CSR_U16(frm); 166 167 p_indent(level, frm); 168 printf("%s: handle %d length %d\n", str, handle, length); 169 } 170 171 static inline void handle_clock_dump(int level, char *str, struct frame *frm) 172 { 173 uint16_t handle; 174 uint32_t clock; 175 176 handle = CSR_U16(frm); 177 clock = CSR_U32(frm); 178 179 p_indent(level, frm); 180 printf("%s: handle %d clock 0x%4.4x\n", str, handle, clock); 181 } 182 183 static inline void radiotest_dump(int level, char *str, struct frame *frm) 184 { 185 uint16_t testid; 186 187 testid = CSR_U16(frm); 188 189 p_indent(level, frm); 190 printf("%s: test id %d\n", str, testid); 191 192 raw_dump(level, frm); 193 } 194 195 static inline void psmemtype_dump(int level, char *str, struct frame *frm) 196 { 197 uint16_t store, type; 198 199 store = CSR_U16(frm); 200 type = CSR_U16(frm); 201 202 p_indent(level, frm); 203 printf("%s: store 0x%4.4x type %d\n", str, store, type); 204 } 205 206 static inline void psnext_dump(int level, char *str, struct frame *frm) 207 { 208 uint16_t key, stores, next; 209 210 key = CSR_U16(frm); 211 stores = CSR_U16(frm); 212 next = CSR_U16(frm); 213 214 p_indent(level, frm); 215 printf("%s: key 0x%4.4x stores 0x%4.4x next 0x%4.4x\n", str, key, stores, next); 216 } 217 218 static inline void pssize_dump(int level, char *str, struct frame *frm) 219 { 220 uint16_t key, length; 221 222 key = CSR_U16(frm); 223 length = CSR_U16(frm); 224 225 p_indent(level, frm); 226 printf("%s: key 0x%4.4x %s 0x%4.4x\n", str, key, 227 frm->in ? "len" : "stores", length); 228 } 229 230 static inline void psstores_dump(int level, char *str, struct frame *frm) 231 { 232 uint16_t key, stores; 233 234 key = CSR_U16(frm); 235 stores = CSR_U16(frm); 236 237 p_indent(level, frm); 238 printf("%s: key 0x%4.4x stores 0x%4.4x\n", str, key, stores); 239 } 240 241 static inline void pskey_dump(int level, struct frame *frm) 242 { 243 uint16_t key, length, stores; 244 245 key = CSR_U16(frm); 246 length = CSR_U16(frm); 247 stores = CSR_U16(frm); 248 249 p_indent(level, frm); 250 printf("PSKEY: key 0x%4.4x len %d stores 0x%4.4x\n", key, length, stores); 251 252 switch (key) { 253 case 0x0001: 254 bdaddr_dump(level + 1, "BDADDR", frm); 255 break; 256 case 0x0002: 257 uint16_dump(level + 1, "COUNTRYCODE", frm); 258 break; 259 case 0x0003: 260 uint32_dump(level + 1, "CLASSOFDEVICE", frm); 261 break; 262 case 0x0004: 263 uint16_dump(level + 1, "DEVICE_DRIFT", frm); 264 break; 265 case 0x0005: 266 uint16_dump(level + 1, "DEVICE_JITTER", frm); 267 break; 268 case 0x000d: 269 uint16_dump(level + 1, "MAX_ACLS", frm); 270 break; 271 case 0x000e: 272 uint16_dump(level + 1, "MAX_SCOS", frm); 273 break; 274 case 0x000f: 275 uint16_dump(level + 1, "MAX_REMOTE_MASTERS", frm); 276 break; 277 case 0x00da: 278 uint16_dump(level + 1, "ENC_KEY_LMIN", frm); 279 break; 280 case 0x00db: 281 uint16_dump(level + 1, "ENC_KEY_LMAX", frm); 282 break; 283 case 0x00ef: 284 features_dump(level + 1, "LOCAL_SUPPORTED_FEATURES", frm); 285 break; 286 case 0x0106: 287 commands_dump(level + 1, "LOCAL_SUPPORTED_COMMANDS", frm); 288 break; 289 case 0x010d: 290 uint16_dump(level + 1, "HCI_LMP_LOCAL_VERSION", frm); 291 break; 292 case 0x010e: 293 uint16_dump(level + 1, "LMP_REMOTE_VERSION", frm); 294 break; 295 case 0x01a5: 296 bool_dump(level + 1, "HOSTIO_USE_HCI_EXTN", frm); 297 break; 298 case 0x01ab: 299 bool_dump(level + 1, "HOSTIO_MAP_SCO_PCM", frm); 300 break; 301 case 0x01be: 302 uint16_dump(level + 1, "UART_BAUDRATE", frm); 303 break; 304 case 0x01f6: 305 uint16_dump(level + 1, "ANA_FTRIM", frm); 306 break; 307 case 0x01f9: 308 uint16_dump(level + 1, "HOST_INTERFACE", frm); 309 break; 310 case 0x01fe: 311 uint16_dump(level + 1, "ANA_FREQ", frm); 312 break; 313 case 0x02be: 314 uint16_dump(level + 1, "USB_VENDOR_ID", frm); 315 break; 316 case 0x02bf: 317 uint16_dump(level + 1, "USB_PRODUCT_ID", frm); 318 break; 319 case 0x02cb: 320 uint16_dump(level + 1, "USB_DFU_PRODUCT_ID", frm); 321 break; 322 case 0x03cd: 323 int16_dump(level + 1, "INITIAL_BOOTMODE", frm); 324 break; 325 default: 326 raw_dump(level + 1, frm); 327 break; 328 } 329 } 330 331 static inline void bccmd_dump(int level, struct frame *frm) 332 { 333 uint16_t type, length, seqno, varid, status; 334 335 type = CSR_U16(frm); 336 length = CSR_U16(frm); 337 seqno = CSR_U16(frm); 338 varid = CSR_U16(frm); 339 status = CSR_U16(frm); 340 341 p_indent(level, frm); 342 printf("BCCMD: %s: len %d seqno %d varid 0x%4.4x status %d\n", 343 type2str(type), length, seqno, varid, status); 344 345 if (!(parser.flags & DUMP_VERBOSE)) { 346 raw_dump(level + 1, frm); 347 return; 348 } 349 350 switch (varid) { 351 case 0x000b: 352 valueless_dump(level + 1, "PS_CLR_ALL", frm); 353 break; 354 case 0x000c: 355 valueless_dump(level + 1, "PS_FACTORY_SET", frm); 356 break; 357 case 0x082d: 358 uint16_dump(level + 1, "PS_CLR_ALL_STORES", frm); 359 break; 360 case 0x2801: 361 uint16_dump(level + 1, "BC01_STATUS", frm); 362 break; 363 case 0x2819: 364 uint16_dump(level + 1, "BUILDID", frm); 365 break; 366 case 0x281a: 367 uint16_dump(level + 1, "CHIPVER", frm); 368 break; 369 case 0x281b: 370 uint16_dump(level + 1, "CHIPREV", frm); 371 break; 372 case 0x2825: 373 uint16_dump(level + 1, "INTERFACE_VERSION", frm); 374 break; 375 case 0x282a: 376 uint16_dump(level + 1, "RAND", frm); 377 break; 378 case 0x282c: 379 uint16_dump(level + 1, "MAX_CRYPT_KEY_LENGTH", frm); 380 break; 381 case 0x2833: 382 uint16_dump(level + 1, "E2_APP_SIZE", frm); 383 break; 384 case 0x2836: 385 uint16_dump(level + 1, "CHIPANAREV", frm); 386 break; 387 case 0x2838: 388 uint16_dump(level + 1, "BUILDID_LOADER", frm); 389 break; 390 case 0x2c00: 391 uint32_dump(level + 1, "BT_CLOCK", frm); 392 break; 393 case 0x3005: 394 psnext_dump(level + 1, "PS_NEXT", frm); 395 break; 396 case 0x3006: 397 pssize_dump(level + 1, "PS_SIZE", frm); 398 break; 399 case 0x3008: 400 handle_length_dump(level + 1, "CRYPT_KEY_LENGTH", frm); 401 break; 402 case 0x3009: 403 handle_clock_dump(level + 1, "PICONET_INSTANCE", frm); 404 break; 405 case 0x300a: 406 complex_dump(level + 1, "GET_CLR_EVT", frm); 407 break; 408 case 0x300b: 409 complex_dump(level + 1, "GET_NEXT_BUILDDEF", frm); 410 break; 411 case 0x300e: 412 complex_dump(level + 1, "E2_DEVICE", frm); 413 break; 414 case 0x300f: 415 complex_dump(level + 1, "E2_APP_DATA", frm); 416 break; 417 case 0x3012: 418 psmemtype_dump(level + 1, "PS_MEMORY_TYPE", frm); 419 break; 420 case 0x301c: 421 complex_dump(level + 1, "READ_BUILD_NAME", frm); 422 break; 423 case 0x4001: 424 valueless_dump(level + 1, "COLD_RESET", frm); 425 break; 426 case 0x4002: 427 valueless_dump(level + 1, "WARM_RESET", frm); 428 break; 429 case 0x4003: 430 valueless_dump(level + 1, "COLD_HALT", frm); 431 break; 432 case 0x4004: 433 valueless_dump(level + 1, "WARM_HALT", frm); 434 break; 435 case 0x4005: 436 valueless_dump(level + 1, "INIT_BT_STACK", frm); 437 break; 438 case 0x4006: 439 valueless_dump(level + 1, "ACTIVATE_BT_STACK", frm); 440 break; 441 case 0x4007: 442 valueless_dump(level + 1, "ENABLE_TX", frm); 443 break; 444 case 0x4008: 445 valueless_dump(level + 1, "DISABLE_TX", frm); 446 break; 447 case 0x4009: 448 valueless_dump(level + 1, "RECAL", frm); 449 break; 450 case 0x400d: 451 valueless_dump(level + 1, "PS_FACTORY_RESTORE", frm); 452 break; 453 case 0x400e: 454 valueless_dump(level + 1, "PS_FACTORY_RESTORE_ALL", frm); 455 break; 456 case 0x400f: 457 valueless_dump(level + 1, "PS_DEFRAG_RESET", frm); 458 break; 459 case 0x4011: 460 valueless_dump(level + 1, "HOPPING_ON", frm); 461 break; 462 case 0x4012: 463 valueless_dump(level + 1, "CANCEL_PAGE", frm); 464 break; 465 case 0x4818: 466 uint16_dump(level + 1, "PS_CLR", frm); 467 break; 468 case 0x481c: 469 uint16_dump(level + 1, "MAP_SCO_PCM", frm); 470 break; 471 case 0x482e: 472 uint16_dump(level + 1, "SINGLE_CHAN", frm); 473 break; 474 case 0x5004: 475 radiotest_dump(level + 1, "RADIOTEST", frm); 476 break; 477 case 0x500c: 478 psstores_dump(level + 1, "PS_CLR_STORES", frm); 479 break; 480 case 0x6000: 481 valueless_dump(level + 1, "NO_VARIABLE", frm); 482 break; 483 case 0x6802: 484 uint16_dump(level + 1, "CONFIG_UART", frm); 485 break; 486 case 0x6805: 487 uint16_dump(level + 1, "PANIC_ARG", frm); 488 break; 489 case 0x6806: 490 uint16_dump(level + 1, "FAULT_ARG", frm); 491 break; 492 case 0x6827: 493 int8_dump(level + 1, "MAX_TX_POWER", frm); 494 break; 495 case 0x682b: 496 int8_dump(level + 1, "DEFAULT_TX_POWER", frm); 497 break; 498 case 0x7003: 499 pskey_dump(level + 1, frm); 500 break; 501 default: 502 raw_dump(level + 1, frm); 503 break; 504 } 505 } 506 507 static char *cid2str(uint8_t cid) 508 { 509 switch (cid & 0x3f) { 510 case 0: 511 return "BCSP Internal"; 512 case 1: 513 return "BCSP Link"; 514 case 2: 515 return "BCCMD"; 516 case 3: 517 return "HQ"; 518 case 4: 519 return "Device Mgt"; 520 case 5: 521 return "HCI Cmd/Evt"; 522 case 6: 523 return "HCI ACL"; 524 case 7: 525 return "HCI SCO"; 526 case 8: 527 return "L2CAP"; 528 case 9: 529 return "RFCOMM"; 530 case 10: 531 return "SDP"; 532 case 11: 533 return "Debug"; 534 case 12: 535 return "DFU"; 536 case 13: 537 return "VM"; 538 case 14: 539 return "Unused"; 540 case 15: 541 return "Reserved"; 542 default: 543 return "Unknown"; 544 } 545 } 546 547 static char *frag2str(uint8_t frag) 548 { 549 switch (frag & 0xc0) { 550 case 0x00: 551 return " middle fragment"; 552 case 0x40: 553 return " first fragment"; 554 case 0x80: 555 return " last fragment"; 556 default: 557 return ""; 558 } 559 } 560 561 void csr_dump(int level, struct frame *frm) 562 { 563 uint8_t desc, cid, type; 564 uint16_t handle, master, addr; 565 566 desc = CSR_U8(frm); 567 568 cid = desc & 0x3f; 569 570 switch (cid) { 571 case 2: 572 bccmd_dump(level, frm); 573 break; 574 575 case 20: 576 type = CSR_U8(frm); 577 578 if (!p_filter(FILT_LMP)) { 579 switch (type) { 580 case 0x0f: 581 frm->handle = ((uint8_t *) frm->ptr)[17]; 582 frm->master = 0; 583 frm->len--; 584 lmp_dump(level, frm); 585 return; 586 case 0x10: 587 frm->handle = ((uint8_t *) frm->ptr)[17]; 588 frm->master = 1; 589 frm->len--; 590 lmp_dump(level, frm); 591 return; 592 case 0x12: 593 handle = CSR_U16(frm); 594 master = CSR_U16(frm); 595 addr = CSR_U16(frm); 596 p_indent(level, frm); 597 printf("FHS: handle %d addr %d (%s)\n", handle, 598 addr, master ? "master" : "slave"); 599 if (!master) { 600 char addr[18]; 601 p_ba2str((bdaddr_t *) frm->ptr, addr); 602 p_indent(level + 1, frm); 603 printf("bdaddr %s class " 604 "0x%2.2x%2.2x%2.2x\n", addr, 605 ((uint8_t *) frm->ptr)[8], 606 ((uint8_t *) frm->ptr)[7], 607 ((uint8_t *) frm->ptr)[6]); 608 } 609 return; 610 case 0x7b: 611 p_indent(level, frm); 612 printf("LMP(r): duplicate (same SEQN)\n"); 613 return; 614 } 615 } 616 617 p_indent(level, frm); 618 printf("CSR: Debug (type 0x%2.2x)\n", type); 619 raw_dump(level, frm); 620 break; 621 622 default: 623 p_indent(level, frm); 624 printf("CSR: %s (channel %d)%s\n", cid2str(cid), cid, frag2str(desc)); 625 raw_dump(level, frm); 626 break; 627 } 628 } 629