csr.c 13 KB

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