bluemoon.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2012 Intel Corporation. All rights reserved.
  7. *
  8. *
  9. */
  10. #ifdef HAVE_CONFIG_H
  11. #include <config.h>
  12. #endif
  13. #include <ctype.h>
  14. #include <stdio.h>
  15. #include <fcntl.h>
  16. #include <unistd.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <getopt.h>
  20. #include <sys/stat.h>
  21. #include <sys/param.h>
  22. #include "monitor/bt.h"
  23. #include "src/shared/mainloop.h"
  24. #include "src/shared/util.h"
  25. #include "src/shared/hci.h"
  26. #define CMD_RESET 0xfc01
  27. struct cmd_reset {
  28. uint8_t reset_type;
  29. uint8_t patch_enable;
  30. uint8_t otp_ddc_reload;
  31. uint8_t boot_option;
  32. uint32_t boot_addr;
  33. } __attribute__ ((packed));
  34. #define CMD_NO_OPERATION 0xfc02
  35. #define CMD_READ_VERSION 0xfc05
  36. struct rsp_read_version {
  37. uint8_t status;
  38. uint8_t hw_platform;
  39. uint8_t hw_variant;
  40. uint8_t hw_revision;
  41. uint8_t fw_variant;
  42. uint8_t fw_revision;
  43. uint8_t fw_build_nn;
  44. uint8_t fw_build_cw;
  45. uint8_t fw_build_yy;
  46. uint8_t fw_patch;
  47. } __attribute__ ((packed));
  48. #define CMD_READ_BOOT_PARAMS 0xfc0d
  49. struct rsp_read_boot_params {
  50. uint8_t status;
  51. uint8_t otp_format;
  52. uint8_t otp_content;
  53. uint8_t otp_patch;
  54. uint16_t dev_revid;
  55. uint8_t secure_boot;
  56. uint8_t key_from_hdr;
  57. uint8_t key_type;
  58. uint8_t otp_lock;
  59. uint8_t api_lock;
  60. uint8_t debug_lock;
  61. uint8_t otp_bdaddr[6];
  62. uint8_t min_fw_build_nn;
  63. uint8_t min_fw_build_cw;
  64. uint8_t min_fw_build_yy;
  65. uint8_t limited_cce;
  66. uint8_t unlocked_state;
  67. } __attribute__ ((packed));
  68. #define CMD_WRITE_BOOT_PARAMS 0xfc0e
  69. struct cmd_write_boot_params {
  70. uint32_t boot_addr;
  71. uint8_t fw_build_nn;
  72. uint8_t fw_build_cw;
  73. uint8_t fw_build_yy;
  74. } __attribute__ ((packed));
  75. #define CMD_MANUFACTURER_MODE 0xfc11
  76. struct cmd_manufacturer_mode {
  77. uint8_t mode_switch;
  78. uint8_t reset;
  79. } __attribute__ ((packed));
  80. #define CMD_WRITE_BD_DATA 0xfc2f
  81. struct cmd_write_bd_data {
  82. uint8_t bdaddr[6];
  83. uint8_t reserved1[6];
  84. uint8_t features[8];
  85. uint8_t le_features;
  86. uint8_t reserved2[32];
  87. uint8_t lmp_version;
  88. uint8_t reserved3[26];
  89. } __attribute__ ((packed));
  90. #define CMD_READ_BD_DATA 0xfc30
  91. struct rsp_read_bd_data {
  92. uint8_t status;
  93. uint8_t bdaddr[6];
  94. uint8_t reserved1[6];
  95. uint8_t features[8];
  96. uint8_t le_features;
  97. uint8_t reserved2[32];
  98. uint8_t lmp_version;
  99. uint8_t reserved3[26];
  100. } __attribute__ ((packed));
  101. #define CMD_WRITE_BD_ADDRESS 0xfc31
  102. struct cmd_write_bd_address {
  103. uint8_t bdaddr[6];
  104. } __attribute__ ((packed));
  105. #define CMD_ACT_DEACT_TRACES 0xfc43
  106. struct cmd_act_deact_traces {
  107. uint8_t tx_trace;
  108. uint8_t tx_arq;
  109. uint8_t rx_trace;
  110. } __attribute__ ((packed));
  111. #define CMD_TRIGGER_EXCEPTION 0xfc4d
  112. struct cmd_trigger_exception {
  113. uint8_t type;
  114. } __attribute__ ((packed));
  115. #define CMD_DDC_CONFIG_WRITE 0xfc8b
  116. #define CMD_MEMORY_WRITE 0xfc8e
  117. static struct bt_hci *hci_dev;
  118. static uint16_t hci_index = 0;
  119. #define FIRMWARE_BASE_PATH "/lib/firmware"
  120. static bool set_bdaddr = false;
  121. static const char *set_bdaddr_value = NULL;
  122. static bool get_bddata = false;
  123. static bool load_firmware = false;
  124. static const char *load_firmware_value = NULL;
  125. static uint8_t *firmware_data = NULL;
  126. static size_t firmware_size = 0;
  127. static size_t firmware_offset = 0;
  128. static bool check_firmware = false;
  129. static const char *check_firmware_value = NULL;
  130. uint8_t manufacturer_mode_reset = 0x00;
  131. static bool use_manufacturer_mode = false;
  132. static bool set_traces = false;
  133. static bool set_exception = false;
  134. static bool reset_on_exit = false;
  135. static bool cold_boot = false;
  136. static void reset_complete(const void *data, uint8_t size, void *user_data)
  137. {
  138. uint8_t status = *((uint8_t *) data);
  139. if (status) {
  140. fprintf(stderr, "Failed to reset (0x%02x)\n", status);
  141. mainloop_quit();
  142. return;
  143. }
  144. mainloop_quit();
  145. }
  146. static void cold_boot_complete(const void *data, uint8_t size, void *user_data)
  147. {
  148. uint8_t status = *((uint8_t *) data);
  149. if (status) {
  150. fprintf(stderr, "Failed to cold boot (0x%02x)\n", status);
  151. mainloop_quit();
  152. return;
  153. }
  154. if (reset_on_exit) {
  155. bt_hci_send(hci_dev, BT_HCI_CMD_RESET, NULL, 0,
  156. reset_complete, NULL, NULL);
  157. return;
  158. }
  159. mainloop_quit();
  160. }
  161. static void leave_manufacturer_mode_complete(const void *data, uint8_t size,
  162. void *user_data)
  163. {
  164. uint8_t status = *((uint8_t *) data);
  165. if (status) {
  166. fprintf(stderr, "Failed to leave manufacturer mode (0x%02x)\n",
  167. status);
  168. mainloop_quit();
  169. return;
  170. }
  171. if (reset_on_exit) {
  172. bt_hci_send(hci_dev, BT_HCI_CMD_RESET, NULL, 0,
  173. reset_complete, NULL, NULL);
  174. return;
  175. }
  176. mainloop_quit();
  177. }
  178. static void shutdown_device(void)
  179. {
  180. bt_hci_flush(hci_dev);
  181. free(firmware_data);
  182. if (use_manufacturer_mode) {
  183. struct cmd_manufacturer_mode cmd;
  184. cmd.mode_switch = 0x00;
  185. cmd.reset = manufacturer_mode_reset;
  186. bt_hci_send(hci_dev, CMD_MANUFACTURER_MODE, &cmd, sizeof(cmd),
  187. leave_manufacturer_mode_complete, NULL, NULL);
  188. return;
  189. }
  190. if (reset_on_exit) {
  191. bt_hci_send(hci_dev, BT_HCI_CMD_RESET, NULL, 0,
  192. reset_complete, NULL, NULL);
  193. return;
  194. }
  195. mainloop_quit();
  196. }
  197. static void write_bd_address_complete(const void *data, uint8_t size,
  198. void *user_data)
  199. {
  200. uint8_t status = *((uint8_t *) data);
  201. if (status) {
  202. fprintf(stderr, "Failed to write address (0x%02x)\n", status);
  203. mainloop_quit();
  204. return;
  205. }
  206. shutdown_device();
  207. }
  208. static void read_bd_addr_complete(const void *data, uint8_t size,
  209. void *user_data)
  210. {
  211. const struct bt_hci_rsp_read_bd_addr *rsp = data;
  212. struct cmd_write_bd_address cmd;
  213. if (rsp->status) {
  214. fprintf(stderr, "Failed to read address (0x%02x)\n",
  215. rsp->status);
  216. mainloop_quit();
  217. shutdown_device();
  218. return;
  219. }
  220. if (set_bdaddr_value) {
  221. fprintf(stderr, "Setting address is not supported\n");
  222. mainloop_quit();
  223. return;
  224. }
  225. printf("Controller Address\n");
  226. printf("\tOld BD_ADDR: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
  227. rsp->bdaddr[5], rsp->bdaddr[4],
  228. rsp->bdaddr[3], rsp->bdaddr[2],
  229. rsp->bdaddr[1], rsp->bdaddr[0]);
  230. memcpy(cmd.bdaddr, rsp->bdaddr, 6);
  231. cmd.bdaddr[0] = (hci_index & 0xff);
  232. printf("\tNew BD_ADDR: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
  233. cmd.bdaddr[5], cmd.bdaddr[4],
  234. cmd.bdaddr[3], cmd.bdaddr[2],
  235. cmd.bdaddr[1], cmd.bdaddr[0]);
  236. bt_hci_send(hci_dev, CMD_WRITE_BD_ADDRESS, &cmd, sizeof(cmd),
  237. write_bd_address_complete, NULL, NULL);
  238. }
  239. static void act_deact_traces_complete(const void *data, uint8_t size,
  240. void *user_data)
  241. {
  242. uint8_t status = *((uint8_t *) data);
  243. if (status) {
  244. fprintf(stderr, "Failed to activate traces (0x%02x)\n", status);
  245. shutdown_device();
  246. return;
  247. }
  248. shutdown_device();
  249. }
  250. static void act_deact_traces(void)
  251. {
  252. struct cmd_act_deact_traces cmd;
  253. cmd.tx_trace = 0x03;
  254. cmd.tx_arq = 0x03;
  255. cmd.rx_trace = 0x03;
  256. bt_hci_send(hci_dev, CMD_ACT_DEACT_TRACES, &cmd, sizeof(cmd),
  257. act_deact_traces_complete, NULL, NULL);
  258. }
  259. static void trigger_exception(void)
  260. {
  261. struct cmd_trigger_exception cmd;
  262. cmd.type = 0x00;
  263. bt_hci_send(hci_dev, CMD_TRIGGER_EXCEPTION, &cmd, sizeof(cmd),
  264. NULL, NULL, NULL);
  265. shutdown_device();
  266. }
  267. static void write_bd_data_complete(const void *data, uint8_t size,
  268. void *user_data)
  269. {
  270. uint8_t status = *((uint8_t *) data);
  271. if (status) {
  272. fprintf(stderr, "Failed to write data (0x%02x)\n", status);
  273. shutdown_device();
  274. return;
  275. }
  276. if (set_traces) {
  277. act_deact_traces();
  278. return;
  279. }
  280. shutdown_device();
  281. }
  282. static void read_bd_data_complete(const void *data, uint8_t size,
  283. void *user_data)
  284. {
  285. const struct rsp_read_bd_data *rsp = data;
  286. if (rsp->status) {
  287. fprintf(stderr, "Failed to read data (0x%02x)\n", rsp->status);
  288. shutdown_device();
  289. return;
  290. }
  291. printf("Controller Data\n");
  292. printf("\tBD_ADDR: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
  293. rsp->bdaddr[5], rsp->bdaddr[4],
  294. rsp->bdaddr[3], rsp->bdaddr[2],
  295. rsp->bdaddr[1], rsp->bdaddr[0]);
  296. printf("\tLMP Version: %u\n", rsp->lmp_version);
  297. printf("\tLMP Features: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x"
  298. " 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n",
  299. rsp->features[0], rsp->features[1],
  300. rsp->features[2], rsp->features[3],
  301. rsp->features[4], rsp->features[5],
  302. rsp->features[6], rsp->features[7]);
  303. printf("\tLE Features: 0x%2.2x\n", rsp->le_features);
  304. if (set_bdaddr) {
  305. struct cmd_write_bd_data cmd;
  306. memcpy(cmd.bdaddr, rsp->bdaddr, 6);
  307. cmd.bdaddr[0] = (hci_index & 0xff);
  308. cmd.lmp_version = 0x07;
  309. memcpy(cmd.features, rsp->features, 8);
  310. cmd.le_features = rsp->le_features;
  311. cmd.le_features |= 0x1e;
  312. memcpy(cmd.reserved1, rsp->reserved1, sizeof(cmd.reserved1));
  313. memcpy(cmd.reserved2, rsp->reserved2, sizeof(cmd.reserved2));
  314. memcpy(cmd.reserved3, rsp->reserved3, sizeof(cmd.reserved3));
  315. bt_hci_send(hci_dev, CMD_WRITE_BD_DATA, &cmd, sizeof(cmd),
  316. write_bd_data_complete, NULL, NULL);
  317. return;
  318. }
  319. shutdown_device();
  320. }
  321. static void firmware_command_complete(const void *data, uint8_t size,
  322. void *user_data)
  323. {
  324. uint8_t status = *((uint8_t *) data);
  325. if (status) {
  326. fprintf(stderr, "Failed to load firmware (0x%02x)\n", status);
  327. manufacturer_mode_reset = 0x01;
  328. shutdown_device();
  329. return;
  330. }
  331. if (firmware_offset >= firmware_size) {
  332. printf("Activating firmware\n");
  333. manufacturer_mode_reset = 0x02;
  334. shutdown_device();
  335. return;
  336. }
  337. if (firmware_data[firmware_offset] == 0x01) {
  338. uint16_t opcode;
  339. uint8_t dlen;
  340. opcode = firmware_data[firmware_offset + 2] << 8 |
  341. firmware_data[firmware_offset + 1];
  342. dlen = firmware_data[firmware_offset + 3];
  343. bt_hci_send(hci_dev, opcode, firmware_data +
  344. firmware_offset + 4, dlen,
  345. firmware_command_complete, NULL, NULL);
  346. firmware_offset += dlen + 4;
  347. if (firmware_data[firmware_offset] == 0x02) {
  348. dlen = firmware_data[firmware_offset + 2];
  349. firmware_offset += dlen + 3;
  350. }
  351. } else {
  352. fprintf(stderr, "Invalid packet in firmware\n");
  353. manufacturer_mode_reset = 0x01;
  354. shutdown_device();
  355. }
  356. }
  357. static void enter_manufacturer_mode_complete(const void *data, uint8_t size,
  358. void *user_data)
  359. {
  360. uint8_t status = *((uint8_t *) data);
  361. if (status) {
  362. fprintf(stderr, "Failed to enter manufacturer mode (0x%02x)\n",
  363. status);
  364. mainloop_quit();
  365. return;
  366. }
  367. if (load_firmware) {
  368. uint8_t status = BT_HCI_ERR_SUCCESS;
  369. firmware_command_complete(&status, sizeof(status), NULL);
  370. return;
  371. }
  372. if (get_bddata || set_bdaddr) {
  373. bt_hci_send(hci_dev, CMD_READ_BD_DATA, NULL, 0,
  374. read_bd_data_complete, NULL, NULL);
  375. return;
  376. }
  377. if (set_traces) {
  378. act_deact_traces();
  379. return;
  380. }
  381. if (set_exception) {
  382. trigger_exception();
  383. return;
  384. }
  385. shutdown_device();
  386. }
  387. static void request_firmware(const char *path)
  388. {
  389. unsigned int cmd_num = 0;
  390. unsigned int evt_num = 0;
  391. struct stat st;
  392. ssize_t len;
  393. int fd;
  394. fd = open(path, O_RDONLY);
  395. if (fd < 0) {
  396. fprintf(stderr, "Failed to open firmware %s\n", path);
  397. shutdown_device();
  398. return;
  399. }
  400. if (fstat(fd, &st) < 0) {
  401. fprintf(stderr, "Failed to get firmware size\n");
  402. close(fd);
  403. shutdown_device();
  404. return;
  405. }
  406. firmware_data = malloc(st.st_size);
  407. if (!firmware_data) {
  408. fprintf(stderr, "Failed to allocate firmware buffer\n");
  409. close(fd);
  410. shutdown_device();
  411. return;
  412. }
  413. len = read(fd, firmware_data, st.st_size);
  414. if (len < 0) {
  415. fprintf(stderr, "Failed to read firmware file\n");
  416. close(fd);
  417. shutdown_device();
  418. return;
  419. }
  420. close(fd);
  421. if (len < st.st_size) {
  422. fprintf(stderr, "Firmware size does not match buffer\n");
  423. shutdown_device();
  424. return;
  425. }
  426. firmware_size = len;
  427. if (firmware_data[0] == 0xff)
  428. firmware_offset = 1;
  429. while (firmware_offset < firmware_size) {
  430. uint16_t opcode;
  431. uint8_t evt, dlen;
  432. switch (firmware_data[firmware_offset]) {
  433. case 0x01:
  434. opcode = firmware_data[firmware_offset + 2] << 8 |
  435. firmware_data[firmware_offset + 1];
  436. dlen = firmware_data[firmware_offset + 3];
  437. if (opcode != CMD_MEMORY_WRITE)
  438. printf("Unexpected opcode 0x%02x\n", opcode);
  439. firmware_offset += dlen + 4;
  440. cmd_num++;
  441. break;
  442. case 0x02:
  443. evt = firmware_data[firmware_offset + 1];
  444. dlen = firmware_data[firmware_offset + 2];
  445. if (evt != BT_HCI_EVT_CMD_COMPLETE)
  446. printf("Unexpected event 0x%02x\n", evt);
  447. firmware_offset += dlen + 3;
  448. evt_num++;
  449. break;
  450. default:
  451. fprintf(stderr, "Invalid firmware file\n");
  452. shutdown_device();
  453. return;
  454. }
  455. }
  456. printf("Firmware with %u commands and %u events\n", cmd_num, evt_num);
  457. if (firmware_data[0] == 0xff)
  458. firmware_offset = 1;
  459. }
  460. static void read_boot_params_complete(const void *data, uint8_t size,
  461. void *user_data)
  462. {
  463. const struct rsp_read_boot_params *rsp = data;
  464. if (rsp->status) {
  465. fprintf(stderr, "Failed to read boot params (0x%02x)\n",
  466. rsp->status);
  467. mainloop_quit();
  468. return;
  469. }
  470. if (size != sizeof(*rsp)) {
  471. fprintf(stderr, "Size mismatch for read boot params\n");
  472. mainloop_quit();
  473. return;
  474. }
  475. printf("Secure Boot Parameters\n");
  476. printf("\tOTP Format Version:\t%u\n", rsp->otp_format);
  477. printf("\tOTP Content Version:\t%u\n", rsp->otp_content);
  478. printf("\tOTP ROM Patch Version:\t%u\n", rsp->otp_patch);
  479. printf("\tDevice Revision ID:\t%u\n", le16_to_cpu(rsp->dev_revid));
  480. printf("\tSecure Boot Enable:\t%u\n", rsp->secure_boot);
  481. printf("\tTake Key From Header:\t%u\n", rsp->key_from_hdr);
  482. printf("\tRSA Key Type:\t\t%u\n", rsp->key_type);
  483. printf("\tOTP Lock:\t\t%u\n", rsp->otp_lock);
  484. printf("\tAPI Lock:\t\t%u\n", rsp->api_lock);
  485. printf("\tDebug Lock:\t\t%u\n", rsp->debug_lock);
  486. printf("\tMin FW Build Number:\t%u-%u.%u\n", rsp->min_fw_build_nn,
  487. rsp->min_fw_build_cw, 2000 + rsp->min_fw_build_yy);
  488. printf("\tLimited CCE to ISSC:\t%u\n", rsp->limited_cce);
  489. printf("\tUnlocked State:\t\t%u\n", rsp->unlocked_state);
  490. mainloop_quit();
  491. }
  492. static const struct {
  493. uint8_t val;
  494. const char *str;
  495. } hw_variant_table[] = {
  496. { 0x06, "iBT 1.1 (XG223)" },
  497. { 0x07, "iBT 2.0 (WP)" },
  498. { 0x08, "iBT 2.5 (StP)" },
  499. { 0x09, "iBT 1.5 (AG610)" },
  500. { 0x0a, "iBT 2.1 (AG620)" },
  501. { 0x0b, "iBT 3.0 (LnP)" },
  502. { 0x0c, "iBT 3.0 (WsP)" },
  503. { 0x11, "iBT 3.5 (JfP)" },
  504. { 0x12, "iBT 3.5 (ThP)" },
  505. { 0x13, "iBT 3.5 (HrP)" },
  506. { 0x14, "iBT 3.5 (CcP)" },
  507. { }
  508. };
  509. static const struct {
  510. uint8_t val;
  511. const char *str;
  512. } fw_variant_table[] = {
  513. { 0x01, "iBT 1.0 - iBT 2.5" },
  514. { 0x06, "iBT Bootloader" },
  515. { 0x23, "iBT 3.x Bluetooth FW" },
  516. { }
  517. };
  518. static void read_version_complete(const void *data, uint8_t size,
  519. void *user_data)
  520. {
  521. const struct rsp_read_version *rsp = data;
  522. const char *str;
  523. int i;
  524. if (rsp->status) {
  525. fprintf(stderr, "Failed to read version (0x%02x)\n",
  526. rsp->status);
  527. mainloop_quit();
  528. return;
  529. }
  530. if (size != sizeof(*rsp)) {
  531. fprintf(stderr, "Size mismatch for read version response\n");
  532. mainloop_quit();
  533. return;
  534. }
  535. if (cold_boot) {
  536. struct cmd_reset cmd;
  537. cmd.reset_type = 0x01;
  538. cmd.patch_enable = 0x00;
  539. cmd.otp_ddc_reload = 0x01;
  540. cmd.boot_option = 0x00;
  541. cmd.boot_addr = cpu_to_le32(0x00000000);
  542. bt_hci_send(hci_dev, CMD_RESET, &cmd, sizeof(cmd),
  543. cold_boot_complete, NULL, NULL);
  544. return;
  545. }
  546. if (load_firmware) {
  547. /* This option is only supported for the legacy ROM produce,
  548. * which can be identified by the fw_variant == 0x01
  549. */
  550. if (rsp->fw_variant != 0x01) {
  551. printf("FW Variant: 0x%02x\n", rsp->fw_variant);
  552. fprintf(stderr, "This device is not supported\n");
  553. mainloop_quit();
  554. return;
  555. }
  556. if (load_firmware_value) {
  557. printf("Firmware: %s\n", load_firmware_value);
  558. request_firmware(load_firmware_value);
  559. } else {
  560. char fw_name[PATH_MAX];
  561. snprintf(fw_name, sizeof(fw_name),
  562. "%s/%s/ibt-hw-%x.%x.%x-fw-%x.%x.%x.%x.%x.bseq",
  563. FIRMWARE_BASE_PATH, "intel",
  564. rsp->hw_platform, rsp->hw_variant,
  565. rsp->hw_revision, rsp->fw_variant,
  566. rsp->fw_revision, rsp->fw_build_nn,
  567. rsp->fw_build_cw, rsp->fw_build_yy);
  568. printf("Firmware: %s\n", fw_name);
  569. printf("Patch level: %d\n", rsp->fw_patch);
  570. request_firmware(fw_name);
  571. }
  572. }
  573. if (use_manufacturer_mode) {
  574. struct cmd_manufacturer_mode cmd;
  575. cmd.mode_switch = 0x01;
  576. cmd.reset = 0x00;
  577. bt_hci_send(hci_dev, CMD_MANUFACTURER_MODE, &cmd, sizeof(cmd),
  578. enter_manufacturer_mode_complete, NULL, NULL);
  579. return;
  580. }
  581. if (set_bdaddr) {
  582. bt_hci_send(hci_dev, BT_HCI_CMD_READ_BD_ADDR, NULL, 0,
  583. read_bd_addr_complete, NULL, NULL);
  584. return;
  585. }
  586. printf("Controller Version Information\n");
  587. printf("\tHardware Platform:\t%u\n", rsp->hw_platform);
  588. str = "Reserved";
  589. for (i = 0; hw_variant_table[i].str; i++) {
  590. if (hw_variant_table[i].val == rsp->hw_variant) {
  591. str = hw_variant_table[i].str;
  592. break;
  593. }
  594. }
  595. printf("\tHardware Variant:\t%s (0x%02x)\n", str, rsp->hw_variant);
  596. printf("\tHardware Revision:\t%u.%u\n", rsp->hw_revision >> 4,
  597. rsp->hw_revision & 0x0f);
  598. str = "Reserved";
  599. for (i = 0; fw_variant_table[i].str; i++) {
  600. if (fw_variant_table[i].val == rsp->fw_variant) {
  601. str = fw_variant_table[i].str;
  602. break;
  603. }
  604. }
  605. printf("\tFirmware Variant:\t%s (0x%02x)\n", str, rsp->fw_variant);
  606. printf("\tFirmware Revision:\t%u.%u\n", rsp->fw_revision >> 4,
  607. rsp->fw_revision & 0x0f);
  608. printf("\tFirmware Build Number:\t%u-%u.%u\n", rsp->fw_build_nn,
  609. rsp->fw_build_cw, 2000 + rsp->fw_build_yy);
  610. printf("\tFirmware Patch Number:\t%u\n", rsp->fw_patch);
  611. if (rsp->hw_variant == 0x0b && rsp->fw_variant == 0x06) {
  612. bt_hci_send(hci_dev, CMD_READ_BOOT_PARAMS, NULL, 0,
  613. read_boot_params_complete, NULL, NULL);
  614. return;
  615. }
  616. mainloop_quit();
  617. }
  618. struct ddc {
  619. uint8_t size;
  620. uint16_t id;
  621. uint8_t value[0];
  622. } __attribute__ ((packed));
  623. static unsigned int analyze_ddc(uint8_t *data, ssize_t len)
  624. {
  625. unsigned int ddc_num;
  626. ssize_t offset;
  627. struct ddc *ddc;
  628. ddc_num = 0;
  629. offset = 0;
  630. while (offset < len) {
  631. ddc = (void *)&data[offset];
  632. offset += ddc->size + 1;
  633. ddc_num++;
  634. }
  635. return ddc_num;
  636. }
  637. static void analyze_firmware_bseq(uint8_t *data, ssize_t len)
  638. {
  639. struct cmd_write_bd_data *bddata = NULL;
  640. unsigned int cmd_num;
  641. unsigned int evt_num;
  642. unsigned int ddc_num;
  643. ssize_t offset;
  644. offset = 0;
  645. cmd_num = 0;
  646. evt_num = 0;
  647. ddc_num = 0;
  648. while (offset < len) {
  649. uint8_t type;
  650. struct bt_hci_cmd_hdr *cmd_hdr;
  651. struct bt_hci_evt_hdr *evt_hdr;
  652. type = data[offset];
  653. offset += 1;
  654. /* Command */
  655. if (type == 0x01) {
  656. cmd_hdr = (void *)&data[offset];
  657. if (cmd_hdr->opcode == CMD_WRITE_BD_DATA)
  658. bddata = (void *)&data[offset + 3];
  659. if (cmd_hdr->opcode == CMD_DDC_CONFIG_WRITE)
  660. ddc_num = analyze_ddc((void *)&data[offset + 3],
  661. cmd_hdr->plen);
  662. offset += cmd_hdr->plen + sizeof(*cmd_hdr);
  663. cmd_num++;
  664. } else if (type == 0x02) {
  665. evt_hdr = (void *)&data[offset];
  666. offset += evt_hdr->plen + sizeof(*evt_hdr);
  667. evt_num++;
  668. } else {
  669. fprintf(stderr, "Unknown type: 0x%02x\n", type);
  670. return;
  671. }
  672. }
  673. printf("Command count:\t%d\n", cmd_num);
  674. printf("Event count:\t%d\n", evt_num);
  675. if (bddata) {
  676. printf("\n");
  677. printf("BD Data Configuration\n");
  678. printf("Features:\t%02X%02X %02X%02X %02X%02X %02X%02X\n",
  679. bddata->features[7], bddata->features[6],
  680. bddata->features[5], bddata->features[4],
  681. bddata->features[3], bddata->features[2],
  682. bddata->features[1], bddata->features[0]);
  683. printf("LE Features:\t%02x\n", bddata->le_features);
  684. printf("LMP Version:\t0x%02x\n", bddata->lmp_version);
  685. }
  686. if (ddc_num)
  687. printf("Total DDC:\t%d\n", ddc_num);
  688. }
  689. struct css_hdr {
  690. uint32_t module_type;
  691. uint32_t header_len;
  692. uint32_t header_version;
  693. uint32_t module_id;
  694. uint32_t module_vendor;
  695. uint32_t date;
  696. uint32_t size;
  697. uint32_t key_size;
  698. uint32_t modulus_size;
  699. uint32_t exponent_size;
  700. uint8_t reserved[88];
  701. } __attribute__ ((packed));
  702. static void analyze_firmware(const char *path)
  703. {
  704. unsigned int cmd_num = 0;
  705. struct css_hdr *css;
  706. const char *ext;
  707. struct stat st;
  708. ssize_t len;
  709. int fd;
  710. fd = open(path, O_RDONLY);
  711. if (fd < 0) {
  712. fprintf(stderr, "Failed to open firmware %s\n", path);
  713. return;
  714. }
  715. if (fstat(fd, &st) < 0) {
  716. fprintf(stderr, "Failed to get firmware size\n");
  717. close(fd);
  718. return;
  719. }
  720. firmware_data = malloc(st.st_size);
  721. if (!firmware_data) {
  722. fprintf(stderr, "Failed to allocate firmware buffer\n");
  723. close(fd);
  724. return;
  725. }
  726. len = read(fd, firmware_data, st.st_size);
  727. if (len < 0) {
  728. fprintf(stderr, "Failed to read firmware file\n");
  729. close(fd);
  730. goto done;
  731. }
  732. close(fd);
  733. if (len != st.st_size) {
  734. fprintf(stderr, "Failed to read complete firmware file\n");
  735. goto done;
  736. }
  737. /* Check the file extension for file type */
  738. ext = strrchr(path, '.');
  739. if (!ext) {
  740. fprintf(stderr, "Unable to get the file extension from path\n");
  741. goto done;
  742. }
  743. if (!strncmp(ext, ".ddc", 4)) {
  744. printf("Firmware file type: DDC file\n\n");
  745. cmd_num = analyze_ddc(firmware_data, len);
  746. printf("Total DDC:\t%d\n", cmd_num);
  747. goto done;
  748. } else if (!strncmp(ext, ".bseq", 5)) {
  749. printf("Firmware file type: BSEQ file\n\n");
  750. analyze_firmware_bseq(firmware_data, len);
  751. goto done;
  752. } else if (!strncmp(ext, ".sfi", 4))
  753. printf("Firmware file type: SFI file\n\n");
  754. else {
  755. fprintf(stderr, "Unknown file extension: %s\n", ext);
  756. goto done;
  757. }
  758. if ((size_t) len < sizeof(*css)) {
  759. fprintf(stderr, "Firmware file is too short\n");
  760. goto done;
  761. }
  762. css = (void *) firmware_data;
  763. printf("Module type:\t%u\n", le32_to_cpu(css->module_type));
  764. printf("Header len:\t%u DWORDs / %u bytes\n",
  765. le32_to_cpu(css->header_len),
  766. le32_to_cpu(css->header_len) * 4);
  767. printf("Header version:\t%u.%u\n",
  768. le32_to_cpu(css->header_version) >> 16,
  769. le32_to_cpu(css->header_version) & 0xffff);
  770. printf("Module ID:\t%u\n", le32_to_cpu(css->module_id));
  771. printf("Module vendor:\t0x%x\n", le32_to_cpu(css->module_vendor));
  772. printf("Date:\t\t%04x-%02x-%02x\n", le32_to_cpu(css->date) >> 16,
  773. le32_to_cpu(css->date) >> 8 & 0xff,
  774. le32_to_cpu(css->date) & 0xff);
  775. printf("Size:\t\t%u DWORDs / %u bytes\n", le32_to_cpu(css->size),
  776. le32_to_cpu(css->size) * 4);
  777. printf("Key size:\t%u DWORDs / %u bytes\n",
  778. le32_to_cpu(css->key_size),
  779. le32_to_cpu(css->key_size) * 4);
  780. printf("Modulus size:\t%u DWORDs / %u bytes\n",
  781. le32_to_cpu(css->modulus_size),
  782. le32_to_cpu(css->modulus_size) * 4);
  783. printf("Exponent size:\t%u DWORDs / %u bytes\n",
  784. le32_to_cpu(css->exponent_size),
  785. le32_to_cpu(css->exponent_size) * 4);
  786. printf("\n");
  787. if ((size_t) len != le32_to_cpu(css->size) * 4) {
  788. fprintf(stderr, "CSS.size does not match file length\n");
  789. goto done;
  790. }
  791. if (le32_to_cpu(css->header_len) != (sizeof(*css) / 4) +
  792. le32_to_cpu(css->key_size) +
  793. le32_to_cpu(css->modulus_size) +
  794. le32_to_cpu(css->exponent_size)) {
  795. fprintf(stderr, "CSS.headerLen does not match data sizes\n");
  796. goto done;
  797. }
  798. firmware_size = le32_to_cpu(css->size) * 4;
  799. firmware_offset = le32_to_cpu(css->header_len) * 4;
  800. while (firmware_offset < firmware_size) {
  801. uint16_t opcode;
  802. uint8_t dlen;
  803. struct cmd_write_boot_params *params;
  804. opcode = get_le16(firmware_data + firmware_offset);
  805. dlen = firmware_data[firmware_offset + 2];
  806. switch (opcode) {
  807. case CMD_WRITE_BOOT_PARAMS:
  808. params = (void *)&firmware_data[firmware_offset + 3];
  809. printf("Boot Parameters\n");
  810. printf("Boot Address:\t0x%08x\n",
  811. le32_to_cpu(params->boot_addr));
  812. printf("Firmware build:\t%u-%u.%u\n",
  813. params->fw_build_nn,
  814. params->fw_build_cw,
  815. 2000 + params->fw_build_yy);
  816. printf("\n");
  817. case CMD_NO_OPERATION:
  818. case CMD_MEMORY_WRITE:
  819. break;
  820. default:
  821. printf("Unexpected opcode 0x%02x\n", opcode);
  822. break;
  823. }
  824. firmware_offset += dlen + 3;
  825. cmd_num++;
  826. }
  827. printf("Firmware with %u commands\n", cmd_num);
  828. done:
  829. free(firmware_data);
  830. }
  831. static void signal_callback(int signum, void *user_data)
  832. {
  833. switch (signum) {
  834. case SIGINT:
  835. case SIGTERM:
  836. mainloop_quit();
  837. break;
  838. }
  839. }
  840. static void usage(void)
  841. {
  842. printf("bluemoon - Bluemoon configuration utility\n"
  843. "Usage:\n");
  844. printf("\tbluemoon [options]\n");
  845. printf("Options:\n"
  846. "\t-A, --bdaddr [addr] Set Bluetooth address\n"
  847. "\t-F, --firmware [file] Load firmware\n"
  848. "\t-C, --check <file> Check firmware image\n"
  849. "\t-R, --reset Reset controller\n"
  850. "\t-B, --coldboot Cold boot controller\n"
  851. "\t-E, --exception Trigger exception\n"
  852. "\t-i, --index <num> Use specified controller\n"
  853. "\t-h, --help Show help options\n");
  854. }
  855. static const struct option main_options[] = {
  856. { "bdaddr", optional_argument, NULL, 'A' },
  857. { "bddata", no_argument, NULL, 'D' },
  858. { "firmware", optional_argument, NULL, 'F' },
  859. { "check", required_argument, NULL, 'C' },
  860. { "traces", no_argument, NULL, 'T' },
  861. { "reset", no_argument, NULL, 'R' },
  862. { "coldboot", no_argument, NULL, 'B' },
  863. { "exception",no_argument, NULL, 'E' },
  864. { "index", required_argument, NULL, 'i' },
  865. { "raw", no_argument, NULL, 'r' },
  866. { "version", no_argument, NULL, 'v' },
  867. { "help", no_argument, NULL, 'h' },
  868. { }
  869. };
  870. int main(int argc, char *argv[])
  871. {
  872. const char *str;
  873. bool use_raw = false;
  874. int exit_status;
  875. for (;;) {
  876. int opt;
  877. opt = getopt_long(argc, argv, "A::DF::C:TRBEi:rvh",
  878. main_options, NULL);
  879. if (opt < 0)
  880. break;
  881. switch (opt) {
  882. case 'A':
  883. if (optarg)
  884. set_bdaddr_value = optarg;
  885. set_bdaddr = true;
  886. break;
  887. case 'D':
  888. use_manufacturer_mode = true;
  889. get_bddata = true;
  890. break;
  891. case 'F':
  892. use_manufacturer_mode = true;
  893. if (optarg)
  894. load_firmware_value = optarg;
  895. load_firmware = true;
  896. break;
  897. case 'C':
  898. check_firmware_value = optarg;
  899. check_firmware = true;
  900. break;
  901. case 'E':
  902. use_manufacturer_mode = true;
  903. set_exception = true;
  904. break;
  905. case 'T':
  906. use_manufacturer_mode = true;
  907. set_traces = true;
  908. break;
  909. case 'R':
  910. reset_on_exit = true;
  911. break;
  912. case 'B':
  913. cold_boot = true;
  914. break;
  915. case 'i':
  916. if (strlen(optarg) > 3 && !strncmp(optarg, "hci", 3))
  917. str = optarg + 3;
  918. else
  919. str = optarg;
  920. if (!isdigit(*str)) {
  921. usage();
  922. return EXIT_FAILURE;
  923. }
  924. hci_index = atoi(str);
  925. break;
  926. case 'r':
  927. use_raw = true;
  928. break;
  929. case 'v':
  930. printf("%s\n", VERSION);
  931. return EXIT_SUCCESS;
  932. case 'h':
  933. usage();
  934. return EXIT_SUCCESS;
  935. default:
  936. return EXIT_FAILURE;
  937. }
  938. }
  939. if (argc - optind > 0) {
  940. fprintf(stderr, "Invalid command line parameters\n");
  941. return EXIT_FAILURE;
  942. }
  943. mainloop_init();
  944. printf("Bluemoon configuration utility ver %s\n", VERSION);
  945. if (check_firmware) {
  946. analyze_firmware(check_firmware_value);
  947. return EXIT_SUCCESS;
  948. }
  949. if (use_raw) {
  950. hci_dev = bt_hci_new_raw_device(hci_index);
  951. if (!hci_dev) {
  952. fprintf(stderr, "Failed to open HCI raw device\n");
  953. return EXIT_FAILURE;
  954. }
  955. } else {
  956. hci_dev = bt_hci_new_user_channel(hci_index);
  957. if (!hci_dev) {
  958. fprintf(stderr, "Failed to open HCI user channel\n");
  959. return EXIT_FAILURE;
  960. }
  961. }
  962. bt_hci_send(hci_dev, CMD_READ_VERSION, NULL, 0,
  963. read_version_complete, NULL, NULL);
  964. exit_status = mainloop_run_with_signal(signal_callback, NULL);
  965. bt_hci_unref(hci_dev);
  966. return exit_status;
  967. }