lmp.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924
  1. // SPDX-License-Identifier: LGPL-2.1-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2011-2014 Intel Corporation
  7. * Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
  8. *
  9. *
  10. */
  11. #ifdef HAVE_CONFIG_H
  12. #include <config.h>
  13. #endif
  14. #define _GNU_SOURCE
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include "src/shared/util.h"
  18. #include "display.h"
  19. #include "packet.h"
  20. #include "bt.h"
  21. #include "lmp.h"
  22. #define COLOR_OPCODE COLOR_MAGENTA
  23. #define COLOR_OPCODE_UNKNOWN COLOR_WHITE_BG
  24. static const char *get_opcode_str(uint16_t opcode);
  25. static void print_opcode(uint16_t opcode)
  26. {
  27. const char *str;
  28. str = get_opcode_str(opcode);
  29. if (!str)
  30. str = "Unknown";
  31. if (opcode & 0xff00)
  32. print_field("Operation: %s (%u/%u)", str,
  33. opcode >> 8, opcode & 0xff);
  34. else
  35. print_field("Operation: %s (%u)", str, opcode);
  36. }
  37. static void name_req(const void *data, uint8_t size)
  38. {
  39. const struct bt_lmp_name_req *pdu = data;
  40. print_field("Offset: %u", pdu->offset);
  41. }
  42. static void name_rsp(const void *data, uint8_t size)
  43. {
  44. const struct bt_lmp_name_rsp *pdu = data;
  45. char str[15];
  46. memcpy(str, pdu->fragment, 14);
  47. str[14] = '\0';
  48. print_field("Offset: %u", pdu->offset);
  49. print_field("Length: %u", pdu->length);
  50. print_field("Fragment: %s", str);
  51. }
  52. static void accepted(const void *data, uint8_t size)
  53. {
  54. const struct bt_lmp_accepted *pdu = data;
  55. print_opcode(pdu->opcode);
  56. }
  57. static void not_accepted(const void *data, uint8_t size)
  58. {
  59. const struct bt_lmp_not_accepted *pdu = data;
  60. print_opcode(pdu->opcode);
  61. packet_print_error("Error code", pdu->error);
  62. }
  63. static void clkoffset_req(const void *data, uint8_t size)
  64. {
  65. }
  66. static void clkoffset_rsp(const void *data, uint8_t size)
  67. {
  68. const struct bt_lmp_clkoffset_rsp *pdu = data;
  69. print_field("Clock offset: 0x%4.4x", le16_to_cpu(pdu->offset));
  70. }
  71. static void detach(const void *data, uint8_t size)
  72. {
  73. const struct bt_lmp_detach *pdu = data;
  74. packet_print_error("Error code", pdu->error);
  75. }
  76. static void au_rand(const void *data, uint8_t size)
  77. {
  78. const struct bt_lmp_au_rand *pdu = data;
  79. packet_hexdump(pdu->number, 16);
  80. }
  81. static void sres(const void *data, uint8_t size)
  82. {
  83. const struct bt_lmp_sres *pdu = data;
  84. packet_hexdump(pdu->response, 4);
  85. }
  86. static void encryption_mode_req(const void *data, uint8_t size)
  87. {
  88. const struct bt_lmp_encryption_mode_req *pdu = data;
  89. const char *str;
  90. switch (pdu->mode) {
  91. case 0x00:
  92. str = "No encryption";
  93. break;
  94. case 0x01:
  95. str = "Encryption";
  96. break;
  97. case 0x02:
  98. str = "Encryption";
  99. break;
  100. default:
  101. str = "Reserved";
  102. break;
  103. }
  104. print_field("Mode: %s (%u)", str, pdu->mode);
  105. }
  106. static void encryption_key_size_req(const void *data, uint8_t size)
  107. {
  108. const struct bt_lmp_encryption_key_size_req *pdu = data;
  109. print_field("Key size: %u", pdu->key_size);
  110. }
  111. static void start_encryption_req(const void *data, uint8_t size)
  112. {
  113. const struct bt_lmp_start_encryption_req *pdu = data;
  114. packet_hexdump(pdu->number, 16);
  115. }
  116. static void stop_encryption_req(const void *data, uint8_t size)
  117. {
  118. }
  119. static void switch_req(const void *data, uint8_t size)
  120. {
  121. const struct bt_lmp_switch_req *pdu = data;
  122. print_field("Instant: 0x%8.8x", le32_to_cpu(pdu->instant));
  123. }
  124. static void unsniff_req(const void *data, uint8_t size)
  125. {
  126. }
  127. static void max_power(const void *data, uint8_t size)
  128. {
  129. }
  130. static void min_power(const void *data, uint8_t size)
  131. {
  132. }
  133. static void auto_rate(const void *data, uint8_t size)
  134. {
  135. }
  136. static void preferred_rate(const void *data, uint8_t size)
  137. {
  138. const struct bt_lmp_preferred_rate *pdu = data;
  139. const char *str;
  140. str = (pdu->rate & 0x01) ? "do not use FEC" : "use FEC";
  141. print_field("Basic data rate: %s (0x%02x)", str, pdu->rate & 0x01);
  142. switch ((pdu->rate & 0x06) >> 1) {
  143. case 0:
  144. str = "No packet-size preference available";
  145. break;
  146. case 1:
  147. str = "use 1-slot packets";
  148. break;
  149. case 2:
  150. str = "use 3-slot packets";
  151. break;
  152. case 3:
  153. str = "use 5-slot packets";
  154. break;
  155. }
  156. print_field("Basic data rate: %s (0x%02x)", str, pdu->rate & 0x06);
  157. switch ((pdu->rate & 0x11) >> 3) {
  158. case 0:
  159. str = "use DM1 packets";
  160. break;
  161. case 1:
  162. str = "use 2 Mb/s packets";
  163. break;
  164. case 2:
  165. str = "use 3 MB/s packets";
  166. break;
  167. case 3:
  168. str = "reserved";
  169. break;
  170. }
  171. print_field("Enhanced data rate: %s (0x%2.2x)", str, pdu->rate & 0x11);
  172. switch ((pdu->rate & 0x60) >> 5) {
  173. case 0:
  174. str = "No packet-size preference available";
  175. break;
  176. case 1:
  177. str = "use 1-slot packets";
  178. break;
  179. case 2:
  180. str = "use 3-slot packets";
  181. break;
  182. case 3:
  183. str = "use 5-slot packets";
  184. break;
  185. }
  186. print_field("Enhanced data rate: %s (0x%2.2x)", str, pdu->rate & 0x60);
  187. }
  188. static void version_req(const void *data, uint8_t size)
  189. {
  190. const struct bt_lmp_version_req *pdu = data;
  191. packet_print_version("Version", pdu->version,
  192. "Subversion", le16_to_cpu(pdu->subversion));
  193. packet_print_company("Company", le16_to_cpu(pdu->company));
  194. }
  195. static void version_res(const void *data, uint8_t size)
  196. {
  197. const struct bt_lmp_version_res *pdu = data;
  198. packet_print_version("Version", pdu->version,
  199. "Subversion", le16_to_cpu(pdu->subversion));
  200. packet_print_company("Company", le16_to_cpu(pdu->company));
  201. }
  202. static void features_req(const void *data, uint8_t size)
  203. {
  204. const struct bt_lmp_features_req *pdu = data;
  205. packet_print_features_lmp(pdu->features, 0x00);
  206. }
  207. static void features_res(const void *data, uint8_t size)
  208. {
  209. const struct bt_lmp_features_res *pdu = data;
  210. packet_print_features_lmp(pdu->features, 0x00);
  211. }
  212. static void max_slot(const void *data, uint8_t size)
  213. {
  214. const struct bt_lmp_max_slot *pdu = data;
  215. print_field("Slots: 0x%4.4x", pdu->slots);
  216. }
  217. static void max_slot_req(const void *data, uint8_t size)
  218. {
  219. const struct bt_lmp_max_slot_req *pdu = data;
  220. print_field("Slots: 0x%4.4x", pdu->slots);
  221. }
  222. static void timing_accuracy_req(const void *data, uint8_t size)
  223. {
  224. }
  225. static void timing_accuracy_res(const void *data, uint8_t size)
  226. {
  227. const struct bt_lmp_timing_accuracy_res *pdu = data;
  228. print_field("Drift: %u ppm", pdu->drift);
  229. print_field("Jitter: %u usec", pdu->jitter);
  230. }
  231. static void setup_complete(const void *data, uint8_t size)
  232. {
  233. }
  234. static void use_semi_permanent_key(const void *data, uint8_t size)
  235. {
  236. }
  237. static void host_connection_req(const void *data, uint8_t size)
  238. {
  239. }
  240. static void slot_offset(const void *data, uint8_t size)
  241. {
  242. const struct bt_lmp_slot_offset *pdu = data;
  243. print_field("Offset: %u usec", le16_to_cpu(pdu->offset));
  244. packet_print_addr("Address", pdu->bdaddr, 0x00);
  245. }
  246. static void page_scan_mode_req(const void *data, uint8_t size)
  247. {
  248. const struct bt_lmp_page_scan_mode_req *pdu = data;
  249. const char *str;
  250. switch (pdu->scheme) {
  251. case 0x00:
  252. str = "Mandatory";
  253. break;
  254. default:
  255. str = "Reserved";
  256. break;
  257. }
  258. print_field("Paging scheme: %s (%u)", str, pdu->scheme);
  259. if (pdu->scheme == 0x00) {
  260. switch (pdu->settings) {
  261. case 0x00:
  262. str = "R0";
  263. break;
  264. case 0x01:
  265. str = "R1";
  266. break;
  267. case 0x02:
  268. str = "R2";
  269. break;
  270. default:
  271. str = "Reserved";
  272. break;
  273. }
  274. } else
  275. str = "Reserved";
  276. print_field("Paging scheme settings: %s (%u)", str, pdu->settings);
  277. }
  278. static void test_activate(const void *data, uint8_t size)
  279. {
  280. }
  281. static void encryption_key_size_mask_req(const void *data, uint8_t size)
  282. {
  283. }
  284. static void set_afh(const void *data, uint8_t size)
  285. {
  286. const struct bt_lmp_set_afh *pdu = data;
  287. const char *str;
  288. print_field("Instant: %u", le32_to_cpu(pdu->instant));
  289. switch (pdu->mode) {
  290. case 0x00:
  291. str = "Disabled";
  292. break;
  293. case 0x01:
  294. str = "Enabled";
  295. break;
  296. default:
  297. str = "Reserved";
  298. break;
  299. }
  300. print_field("Mode: %s (0x%2.2x)", str, pdu->mode);
  301. packet_print_channel_map_lmp(pdu->map);
  302. }
  303. static void encapsulated_header(const void *data, uint8_t size)
  304. {
  305. const struct bt_lmp_encapsulated_header *pdu = data;
  306. const char *str;
  307. print_field("Major type: %u", pdu->major);
  308. print_field("Minor type: %u", pdu->minor);
  309. if (pdu->major == 0x01) {
  310. switch (pdu->minor) {
  311. case 0x01:
  312. str = "P-192 Public Key";
  313. break;
  314. case 0x02:
  315. str = "P-256 Public Key";
  316. break;
  317. default:
  318. str = "Reserved";
  319. break;
  320. }
  321. print_field(" %s", str);
  322. }
  323. print_field("Length: %u", pdu->length);
  324. }
  325. static void encapsulated_payload(const void *data, uint8_t size)
  326. {
  327. const struct bt_lmp_encapsulated_payload *pdu = data;
  328. packet_hexdump(pdu->data, 16);
  329. }
  330. static void simple_pairing_confirm(const void *data, uint8_t size)
  331. {
  332. const struct bt_lmp_simple_pairing_confirm *pdu = data;
  333. packet_hexdump(pdu->value, 16);
  334. }
  335. static void simple_pairing_number(const void *data, uint8_t size)
  336. {
  337. const struct bt_lmp_simple_pairing_number *pdu = data;
  338. packet_hexdump(pdu->value, 16);
  339. }
  340. static void dhkey_check(const void *data, uint8_t size)
  341. {
  342. const struct bt_lmp_dhkey_check *pdu = data;
  343. packet_hexdump(pdu->value, 16);
  344. }
  345. static void accepted_ext(const void *data, uint8_t size)
  346. {
  347. const struct bt_lmp_accepted_ext *pdu = data;
  348. uint16_t opcode;
  349. switch (pdu->escape) {
  350. case 127:
  351. opcode = LMP_ESC4(pdu->opcode);
  352. break;
  353. default:
  354. return;
  355. }
  356. print_opcode(opcode);
  357. }
  358. static void not_accepted_ext(const void *data, uint8_t size)
  359. {
  360. const struct bt_lmp_not_accepted_ext *pdu = data;
  361. uint16_t opcode;
  362. switch (pdu->escape) {
  363. case 127:
  364. opcode = LMP_ESC4(pdu->opcode);
  365. break;
  366. default:
  367. return;
  368. }
  369. print_opcode(opcode);
  370. print_field("Error code: %u", pdu->error);
  371. }
  372. static void features_req_ext(const void *data, uint8_t size)
  373. {
  374. const struct bt_lmp_features_req_ext *pdu = data;
  375. print_field("Features page: %u", pdu->page);
  376. print_field("Max supported page: %u", pdu->max_page);
  377. packet_print_features_lmp(pdu->features, pdu->page);
  378. }
  379. static void features_res_ext(const void *data, uint8_t size)
  380. {
  381. const struct bt_lmp_features_res_ext *pdu = data;
  382. print_field("Features page: %u", pdu->page);
  383. print_field("Max supported page: %u", pdu->max_page);
  384. packet_print_features_lmp(pdu->features, pdu->page);
  385. }
  386. static void packet_type_table_req(const void *data, uint8_t size)
  387. {
  388. const struct bt_lmp_packet_type_table_req *pdu = data;
  389. const char *str;
  390. switch (pdu->table) {
  391. case 0x00:
  392. str = "1 Mbps only";
  393. break;
  394. case 0x01:
  395. str = "2/3 Mbps";
  396. break;
  397. default:
  398. str = "Reserved";
  399. break;
  400. }
  401. print_field("Table: %s (0x%2.2x)", str, pdu->table);
  402. }
  403. static void channel_classification_req(const void *data, uint8_t size)
  404. {
  405. const struct bt_lmp_channel_classification_req *pdu = data;
  406. const char *str;
  407. switch (pdu->mode) {
  408. case 0x00:
  409. str = "Disabled";
  410. break;
  411. case 0x01:
  412. str = "Enabled";
  413. break;
  414. default:
  415. str = "Reserved";
  416. break;
  417. }
  418. print_field("Reporting mode: %s (0x%2.2x)", str, pdu->mode);
  419. print_field("Min interval: 0x%2.2x", pdu->min_interval);
  420. print_field("Max interval: 0x%2.2x", pdu->max_interval);
  421. }
  422. static void channel_classification(const void *data, uint8_t size)
  423. {
  424. const struct bt_lmp_channel_classification *pdu = data;
  425. char str[21];
  426. int i;
  427. for (i = 0; i < 10; i++)
  428. sprintf(str + (i * 2), "%2.2x", pdu->classification[i]);
  429. print_field("Classification: 0x%s", str);
  430. }
  431. static void pause_encryption_req(const void *data, uint8_t size)
  432. {
  433. }
  434. static void resume_encryption_req(const void *data, uint8_t size)
  435. {
  436. }
  437. static void io_capability_req(const void *data, uint8_t size)
  438. {
  439. const struct bt_lmp_io_capability_req *pdu = data;
  440. const char *str;
  441. packet_print_io_capability(pdu->capability);
  442. switch (pdu->oob_data) {
  443. case 0x00:
  444. str = "No authentication data received";
  445. break;
  446. case 0x01:
  447. str = "Authentication data received";
  448. break;
  449. default:
  450. str = "Reserved";
  451. break;
  452. }
  453. print_field("OOB data: %s (0x%2.2x)", str, pdu->oob_data);
  454. packet_print_io_authentication(pdu->authentication);
  455. }
  456. static void io_capability_res(const void *data, uint8_t size)
  457. {
  458. const struct bt_lmp_io_capability_res *pdu = data;
  459. const char *str;
  460. packet_print_io_capability(pdu->capability);
  461. switch (pdu->oob_data) {
  462. case 0x00:
  463. str = "No authentication data received";
  464. break;
  465. case 0x01:
  466. str = "Authentication data received";
  467. break;
  468. default:
  469. str = "Reserved";
  470. break;
  471. }
  472. print_field("OOB data: %s (0x%2.2x)", str, pdu->oob_data);
  473. packet_print_io_authentication(pdu->authentication);
  474. }
  475. static void numeric_comparison_failed(const void *data, uint8_t size)
  476. {
  477. }
  478. static void passkey_failed(const void *data, uint8_t size)
  479. {
  480. }
  481. static void oob_failed(const void *data, uint8_t size)
  482. {
  483. }
  484. static void power_control_req(const void *data, uint8_t size)
  485. {
  486. const struct bt_lmp_power_control_req *pdu = data;
  487. const char *str;
  488. switch (pdu->request) {
  489. case 0x00:
  490. str = "Decrement power one step";
  491. break;
  492. case 0x01:
  493. str = "Increment power one step";
  494. break;
  495. case 0x02:
  496. str = "Increase to maximum power";
  497. break;
  498. default:
  499. str = "Reserved";
  500. break;
  501. }
  502. print_field("Request: %s (0x%2.2x)", str, pdu->request);
  503. }
  504. static void power_control_res(const void *data, uint8_t size)
  505. {
  506. const struct bt_lmp_power_control_res *pdu = data;
  507. const char *str;
  508. print_field("Response: 0x%2.2x", pdu->response);
  509. switch (pdu->response & 0x03) {
  510. case 0x00:
  511. str = "Not supported";
  512. break;
  513. case 0x01:
  514. str = "Changed one step";
  515. break;
  516. case 0x02:
  517. str = "Max power";
  518. break;
  519. case 0x03:
  520. str = "Min power";
  521. break;
  522. default:
  523. str = "Reserved";
  524. break;
  525. }
  526. print_field(" GFSK: %s", str);
  527. switch ((pdu->response & 0x0c) >> 2) {
  528. case 0x00:
  529. str = "Not supported";
  530. break;
  531. case 0x01:
  532. str = "Changed one step";
  533. break;
  534. case 0x02:
  535. str = "Max power";
  536. break;
  537. case 0x03:
  538. str = "Min power";
  539. break;
  540. default:
  541. str = "Reserved";
  542. break;
  543. }
  544. print_field(" DQPSK: %s", str);
  545. switch ((pdu->response & 0x30) >> 4) {
  546. case 0x00:
  547. str = "Not supported";
  548. break;
  549. case 0x01:
  550. str = "Changed one step";
  551. break;
  552. case 0x02:
  553. str = "Max power";
  554. break;
  555. case 0x03:
  556. str = "Min power";
  557. break;
  558. default:
  559. str = "Reserved";
  560. break;
  561. }
  562. print_field(" 8DPSK: %s", str);
  563. }
  564. static void ping_req(const void *data, uint8_t size)
  565. {
  566. }
  567. static void ping_res(const void *data, uint8_t size)
  568. {
  569. }
  570. struct lmp_data {
  571. uint16_t opcode;
  572. const char *str;
  573. void (*func) (const void *data, uint8_t size);
  574. uint8_t size;
  575. bool fixed;
  576. };
  577. static const struct lmp_data lmp_table[] = {
  578. { 1, "LMP_name_req", name_req, 1, true },
  579. { 2, "LMP_name_res", name_rsp, 16, true },
  580. { 3, "LMP_accepted", accepted, 1, true },
  581. { 4, "LMP_not_accepted", not_accepted, 2, true },
  582. { 5, "LMP_clkoffset_req", clkoffset_req, 0, true },
  583. { 6, "LMP_clkoffset_res", clkoffset_rsp, 2, true },
  584. { 7, "LMP_detach", detach, 1, true },
  585. { 8, "LMP_in_rand" },
  586. { 9, "LMP_comb_key" },
  587. { 10, "LMP_unit_key" },
  588. { 11, "LMP_au_rand", au_rand, 16, true },
  589. { 12, "LMP_sres", sres, 4, true },
  590. { 13, "LMP_temp_rand" },
  591. { 14, "LMP_temp_key" },
  592. { 15, "LMP_encryption_mode_req", encryption_mode_req, 1, true },
  593. { 16, "LMP_encryption_key_size_req", encryption_key_size_req, 1, true },
  594. { 17, "LMP_start_encryption_req", start_encryption_req, 16, true },
  595. { 18, "LMP_stop_encryption_req", stop_encryption_req, 0, true },
  596. { 19, "LMP_switch_req", switch_req, 4, true },
  597. { 20, "LMP_hold" },
  598. { 21, "LMP_hold_req" },
  599. { 22, "LMP_sniff" },
  600. { 23, "LMP_sniff_req" },
  601. { 24, "LMP_unsniff_req", unsniff_req, 0, true },
  602. { 25, "LMP_park_req" },
  603. { 26, "LMP_park" },
  604. { 27, "LMP_set_broadcast_scan_window" },
  605. { 28, "LMP_modify_beacon" },
  606. { 29, "LMP_unpark_BD_ADDR_req" },
  607. { 30, "LMP_unpark_PM_ADDR_req" },
  608. { 31, "LMP_incr_power_req" },
  609. { 32, "LMP_decr_power_req" },
  610. { 33, "LMP_max_power", max_power, 0, true },
  611. { 34, "LMP_min_power", min_power, 0, true },
  612. { 35, "LMP_auto_rate", auto_rate, 0, true },
  613. { 36, "LMP_preferred_rate", preferred_rate, 1, true },
  614. { 37, "LMP_version_req", version_req, 5, true },
  615. { 38, "LMP_version_res", version_res, 5, true },
  616. { 39, "LMP_features_req", features_req, 8, true },
  617. { 40, "LMP_features_res", features_res, 8, true },
  618. { 41, "LMP_quality_of_service" },
  619. { 42, "LMP_quality_of_service_req" },
  620. { 43, "LMP_SCO_link_req" },
  621. { 44, "LMP_remove_SCO_link_req" },
  622. { 45, "LMP_max_slot", max_slot, 1, true },
  623. { 46, "LMP_max_slot_req", max_slot_req, 1, true },
  624. { 47, "LMP_timing_accuracy_req", timing_accuracy_req, 0, true },
  625. { 48, "LMP_timing_accuracy_res", timing_accuracy_res, 2, true },
  626. { 49, "LMP_setup_complete", setup_complete, 0, true },
  627. { 50, "LMP_use_semi_permanent_key", use_semi_permanent_key, 0, true },
  628. { 51, "LMP_host_connection_req", host_connection_req, 0, true },
  629. { 52, "LMP_slot_offset", slot_offset, 8, true },
  630. { 53, "LMP_page_mode_req" },
  631. { 54, "LMP_page_scan_mode_req", page_scan_mode_req, 2, true },
  632. { 55, "LMP_supervision_timeout" },
  633. { 56, "LMP_test_activate", test_activate, 0, true },
  634. { 57, "LMP_test_control" },
  635. { 58, "LMP_encryption_key_size_mask_req", encryption_key_size_mask_req, 0, true },
  636. { 59, "LMP_encryption_key_size_mask_res" },
  637. { 60, "LMP_set_AFH", set_afh, 15, true },
  638. { 61, "LMP_encapsulated_header", encapsulated_header, 3, true },
  639. { 62, "LMP_encapsulated_payload", encapsulated_payload, 16, true },
  640. { 63, "LMP_simple_pairing_confirm", simple_pairing_confirm, 16, true },
  641. { 64, "LMP_simple_pairing_number", simple_pairing_number, 16, true },
  642. { 65, "LMP_DHkey_check", dhkey_check, 16, true },
  643. { 66, "LMP_pause_encryption_aes_req" },
  644. { LMP_ESC4(1), "LMP_accepted_ext", accepted_ext, 2, true },
  645. { LMP_ESC4(2), "LMP_not_accepted_ext", not_accepted_ext, 3, true },
  646. { LMP_ESC4(3), "LMP_features_req_ext", features_req_ext, 10, true },
  647. { LMP_ESC4(4), "LMP_features_res_ext", features_res_ext, 10, true },
  648. { LMP_ESC4(5), "LMP_clk_adj" },
  649. { LMP_ESC4(6), "LMP_clk_adj_ack" },
  650. { LMP_ESC4(7), "LMP_clk_adj_req" },
  651. { LMP_ESC4(11), "LMP_packet_type_table_req", packet_type_table_req, 1, true },
  652. { LMP_ESC4(12), "LMP_eSCO_link_req" },
  653. { LMP_ESC4(13), "LMP_remove_eSCO_link_req" },
  654. { LMP_ESC4(16), "LMP_channel_classification_req", channel_classification_req, 5, true },
  655. { LMP_ESC4(17), "LMP_channel_classification", channel_classification, 10, true },
  656. { LMP_ESC4(21), "LMP_sniff_subrating_req" },
  657. { LMP_ESC4(22), "LMP_sniff_subrating_res" },
  658. { LMP_ESC4(23), "LMP_pause_encryption_req", pause_encryption_req, 0, true },
  659. { LMP_ESC4(24), "LMP_resume_encryption_req", resume_encryption_req, 0, true },
  660. { LMP_ESC4(25), "LMP_IO_capability_req", io_capability_req, 3, true },
  661. { LMP_ESC4(26), "LMP_IO_capability_res", io_capability_res, 3, true },
  662. { LMP_ESC4(27), "LMP_numeric_comparison_failed", numeric_comparison_failed, 0, true },
  663. { LMP_ESC4(28), "LMP_passkey_failed", passkey_failed, 0, true },
  664. { LMP_ESC4(29), "LMP_oob_failed", oob_failed, 0, true },
  665. { LMP_ESC4(30), "LMP_keypress_notification" },
  666. { LMP_ESC4(31), "LMP_power_control_req", power_control_req, 1, true },
  667. { LMP_ESC4(32), "LMP_power_control_res", power_control_res, 1, true },
  668. { LMP_ESC4(33), "LMP_ping_req", ping_req, 0, true },
  669. { LMP_ESC4(34), "LMP_ping_res", ping_res, 0, true },
  670. { LMP_ESC4(35), "LMP_SAM_set_type0" },
  671. { LMP_ESC4(36), "LMP_SAM_define_map" },
  672. { LMP_ESC4(37), "LMP_SAM_switch" },
  673. { }
  674. };
  675. static const char *get_opcode_str(uint16_t opcode)
  676. {
  677. int i;
  678. for (i = 0; lmp_table[i].str; i++) {
  679. if (lmp_table[i].opcode == opcode)
  680. return lmp_table[i].str;
  681. }
  682. return NULL;
  683. }
  684. void lmp_packet(const void *data, uint8_t size, bool padded)
  685. {
  686. const struct lmp_data *lmp_data = NULL;
  687. const char *opcode_color, *opcode_str;
  688. uint16_t opcode;
  689. uint8_t tid, off;
  690. const char *tid_str;
  691. int i;
  692. tid = ((const uint8_t *) data)[0] & 0x01;
  693. opcode = (((const uint8_t *) data)[0] & 0xfe) >> 1;
  694. tid_str = tid == 0x00 ? "Central" : "Peripheral";
  695. switch (opcode) {
  696. case 127:
  697. if (size < 2) {
  698. print_text(COLOR_ERROR, "extended opcode too short");
  699. packet_hexdump(data, size);
  700. return;
  701. }
  702. opcode = LMP_ESC4(((const uint8_t *) data)[1]);
  703. off = 2;
  704. break;
  705. case 126:
  706. case 125:
  707. case 124:
  708. return;
  709. default:
  710. off = 1;
  711. break;
  712. }
  713. for (i = 0; lmp_table[i].str; i++) {
  714. if (lmp_table[i].opcode == opcode) {
  715. lmp_data = &lmp_table[i];
  716. break;
  717. }
  718. }
  719. if (lmp_data) {
  720. if (lmp_data->func)
  721. opcode_color = COLOR_OPCODE;
  722. else
  723. opcode_color = COLOR_OPCODE_UNKNOWN;
  724. opcode_str = lmp_data->str;
  725. } else {
  726. opcode_color = COLOR_OPCODE_UNKNOWN;
  727. opcode_str = "Unknown";
  728. }
  729. if (opcode & 0xff00)
  730. print_indent(6, opcode_color, "", opcode_str, COLOR_OFF,
  731. " (%u/%u) %s transaction (%u)",
  732. opcode >> 8, opcode & 0xff, tid_str, tid);
  733. else
  734. print_indent(6, opcode_color, "", opcode_str, COLOR_OFF,
  735. " (%u) %s transaction (%d)",
  736. opcode, tid_str, tid);
  737. if (!lmp_data || !lmp_data->func) {
  738. packet_hexdump(data + off, size - off);
  739. return;
  740. }
  741. if (lmp_data->fixed && !padded) {
  742. if (size - off != lmp_data->size) {
  743. print_text(COLOR_ERROR, "invalid packet size");
  744. packet_hexdump(data + off, size - off);
  745. return;
  746. }
  747. } else {
  748. if (size - off < lmp_data->size) {
  749. print_text(COLOR_ERROR, "too short packet");
  750. packet_hexdump(data + off, size - off);
  751. return;
  752. }
  753. }
  754. lmp_data->func(data + off, size - off);
  755. }
  756. void lmp_todo(void)
  757. {
  758. int i;
  759. printf("LMP operations with missing decodings:\n");
  760. for (i = 0; lmp_table[i].str; i++) {
  761. if (lmp_table[i].func)
  762. continue;
  763. printf("\t%s\n", lmp_table[i].str);
  764. }
  765. }