bdaddr.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
  7. *
  8. *
  9. */
  10. #ifdef HAVE_CONFIG_H
  11. #include <config.h>
  12. #endif
  13. #include <stdio.h>
  14. #include <errno.h>
  15. #include <stdlib.h>
  16. #include <getopt.h>
  17. #include <unistd.h>
  18. #include <sys/ioctl.h>
  19. #include <sys/socket.h>
  20. #include "lib/bluetooth.h"
  21. #include "lib/hci.h"
  22. #include "lib/hci_lib.h"
  23. #include "src/oui.h"
  24. static int transient = 0;
  25. static int generic_reset_device(int dd)
  26. {
  27. bdaddr_t bdaddr;
  28. int err;
  29. err = hci_send_cmd(dd, 0x03, 0x0003, 0, NULL);
  30. if (err < 0)
  31. return err;
  32. return hci_read_bd_addr(dd, &bdaddr, 10000);
  33. }
  34. #define OCF_ERICSSON_WRITE_BD_ADDR 0x000d
  35. typedef struct {
  36. bdaddr_t bdaddr;
  37. } __attribute__ ((packed)) ericsson_write_bd_addr_cp;
  38. static int ericsson_write_bd_addr(int dd, bdaddr_t *bdaddr)
  39. {
  40. struct hci_request rq;
  41. ericsson_write_bd_addr_cp cp;
  42. memset(&cp, 0, sizeof(cp));
  43. bacpy(&cp.bdaddr, bdaddr);
  44. memset(&rq, 0, sizeof(rq));
  45. rq.ogf = OGF_VENDOR_CMD;
  46. rq.ocf = OCF_ERICSSON_WRITE_BD_ADDR;
  47. rq.cparam = &cp;
  48. rq.clen = sizeof(cp);
  49. rq.rparam = NULL;
  50. rq.rlen = 0;
  51. if (hci_send_req(dd, &rq, 1000) < 0)
  52. return -1;
  53. return 0;
  54. }
  55. #define OCF_ERICSSON_STORE_IN_FLASH 0x0022
  56. typedef struct {
  57. uint8_t user_id;
  58. uint8_t flash_length;
  59. uint8_t flash_data[253];
  60. } __attribute__ ((packed)) ericsson_store_in_flash_cp;
  61. static int ericsson_store_in_flash(int dd, uint8_t user_id, uint8_t flash_length, uint8_t *flash_data)
  62. {
  63. struct hci_request rq;
  64. ericsson_store_in_flash_cp cp;
  65. memset(&cp, 0, sizeof(cp));
  66. cp.user_id = user_id;
  67. cp.flash_length = flash_length;
  68. if (flash_length > 0)
  69. memcpy(cp.flash_data, flash_data, flash_length);
  70. memset(&rq, 0, sizeof(rq));
  71. rq.ogf = OGF_VENDOR_CMD;
  72. rq.ocf = OCF_ERICSSON_STORE_IN_FLASH;
  73. rq.cparam = &cp;
  74. rq.clen = sizeof(cp);
  75. rq.rparam = NULL;
  76. rq.rlen = 0;
  77. if (hci_send_req(dd, &rq, 1000) < 0)
  78. return -1;
  79. return 0;
  80. }
  81. static int csr_write_bd_addr(int dd, bdaddr_t *bdaddr)
  82. {
  83. unsigned char cmd[] = { 0x02, 0x00, 0x0c, 0x00, 0x11, 0x47, 0x03, 0x70,
  84. 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00,
  85. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  86. unsigned char cp[254], rp[254];
  87. struct hci_request rq;
  88. if (transient)
  89. cmd[14] = 0x08;
  90. cmd[16] = bdaddr->b[2];
  91. cmd[17] = 0x00;
  92. cmd[18] = bdaddr->b[0];
  93. cmd[19] = bdaddr->b[1];
  94. cmd[20] = bdaddr->b[3];
  95. cmd[21] = 0x00;
  96. cmd[22] = bdaddr->b[4];
  97. cmd[23] = bdaddr->b[5];
  98. memset(&cp, 0, sizeof(cp));
  99. cp[0] = 0xc2;
  100. memcpy(cp + 1, cmd, sizeof(cmd));
  101. memset(&rq, 0, sizeof(rq));
  102. rq.ogf = OGF_VENDOR_CMD;
  103. rq.ocf = 0x00;
  104. rq.event = EVT_VENDOR;
  105. rq.cparam = cp;
  106. rq.clen = sizeof(cmd) + 1;
  107. rq.rparam = rp;
  108. rq.rlen = sizeof(rp);
  109. if (hci_send_req(dd, &rq, 2000) < 0)
  110. return -1;
  111. if (rp[0] != 0xc2) {
  112. errno = EIO;
  113. return -1;
  114. }
  115. if ((rp[9] + (rp[10] << 8)) != 0) {
  116. errno = ENXIO;
  117. return -1;
  118. }
  119. return 0;
  120. }
  121. static int csr_reset_device(int dd)
  122. {
  123. unsigned char cmd[] = { 0x02, 0x00, 0x09, 0x00,
  124. 0x00, 0x00, 0x01, 0x40, 0x00, 0x00,
  125. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  126. unsigned char cp[254], rp[254];
  127. struct hci_request rq;
  128. if (transient)
  129. cmd[6] = 0x02;
  130. memset(&cp, 0, sizeof(cp));
  131. cp[0] = 0xc2;
  132. memcpy(cp + 1, cmd, sizeof(cmd));
  133. memset(&rq, 0, sizeof(rq));
  134. rq.ogf = OGF_VENDOR_CMD;
  135. rq.ocf = 0x00;
  136. rq.event = EVT_VENDOR;
  137. rq.cparam = cp;
  138. rq.clen = sizeof(cmd) + 1;
  139. rq.rparam = rp;
  140. rq.rlen = sizeof(rp);
  141. if (hci_send_req(dd, &rq, 2000) < 0)
  142. return -1;
  143. return 0;
  144. }
  145. #define OCF_TI_WRITE_BD_ADDR 0x0006
  146. typedef struct {
  147. bdaddr_t bdaddr;
  148. } __attribute__ ((packed)) ti_write_bd_addr_cp;
  149. static int ti_write_bd_addr(int dd, bdaddr_t *bdaddr)
  150. {
  151. struct hci_request rq;
  152. ti_write_bd_addr_cp cp;
  153. memset(&cp, 0, sizeof(cp));
  154. bacpy(&cp.bdaddr, bdaddr);
  155. memset(&rq, 0, sizeof(rq));
  156. rq.ogf = OGF_VENDOR_CMD;
  157. rq.ocf = OCF_TI_WRITE_BD_ADDR;
  158. rq.cparam = &cp;
  159. rq.clen = sizeof(cp);
  160. rq.rparam = NULL;
  161. rq.rlen = 0;
  162. if (hci_send_req(dd, &rq, 1000) < 0)
  163. return -1;
  164. return 0;
  165. }
  166. #define OCF_BCM_WRITE_BD_ADDR 0x0001
  167. typedef struct {
  168. bdaddr_t bdaddr;
  169. } __attribute__ ((packed)) bcm_write_bd_addr_cp;
  170. static int bcm_write_bd_addr(int dd, bdaddr_t *bdaddr)
  171. {
  172. struct hci_request rq;
  173. bcm_write_bd_addr_cp cp;
  174. memset(&cp, 0, sizeof(cp));
  175. bacpy(&cp.bdaddr, bdaddr);
  176. memset(&rq, 0, sizeof(rq));
  177. rq.ogf = OGF_VENDOR_CMD;
  178. rq.ocf = OCF_BCM_WRITE_BD_ADDR;
  179. rq.cparam = &cp;
  180. rq.clen = sizeof(cp);
  181. rq.rparam = NULL;
  182. rq.rlen = 0;
  183. if (hci_send_req(dd, &rq, 1000) < 0)
  184. return -1;
  185. return 0;
  186. }
  187. #define OCF_ZEEVO_WRITE_BD_ADDR 0x0001
  188. typedef struct {
  189. bdaddr_t bdaddr;
  190. } __attribute__ ((packed)) zeevo_write_bd_addr_cp;
  191. static int zeevo_write_bd_addr(int dd, bdaddr_t *bdaddr)
  192. {
  193. struct hci_request rq;
  194. zeevo_write_bd_addr_cp cp;
  195. memset(&cp, 0, sizeof(cp));
  196. bacpy(&cp.bdaddr, bdaddr);
  197. memset(&rq, 0, sizeof(rq));
  198. rq.ogf = OGF_VENDOR_CMD;
  199. rq.ocf = OCF_ZEEVO_WRITE_BD_ADDR;
  200. rq.cparam = &cp;
  201. rq.clen = sizeof(cp);
  202. rq.rparam = NULL;
  203. rq.rlen = 0;
  204. if (hci_send_req(dd, &rq, 1000) < 0)
  205. return -1;
  206. return 0;
  207. }
  208. #define OCF_MRVL_WRITE_BD_ADDR 0x0022
  209. typedef struct {
  210. uint8_t parameter_id;
  211. uint8_t bdaddr_len;
  212. bdaddr_t bdaddr;
  213. } __attribute__ ((packed)) mrvl_write_bd_addr_cp;
  214. static int mrvl_write_bd_addr(int dd, bdaddr_t *bdaddr)
  215. {
  216. mrvl_write_bd_addr_cp cp;
  217. memset(&cp, 0, sizeof(cp));
  218. cp.parameter_id = 0xFE;
  219. cp.bdaddr_len = 6;
  220. bacpy(&cp.bdaddr, bdaddr);
  221. if (hci_send_cmd(dd, OGF_VENDOR_CMD, OCF_MRVL_WRITE_BD_ADDR,
  222. sizeof(cp), &cp) < 0)
  223. return -1;
  224. sleep(1);
  225. return 0;
  226. }
  227. static int st_write_bd_addr(int dd, bdaddr_t *bdaddr)
  228. {
  229. return ericsson_store_in_flash(dd, 0xfe, 6, (uint8_t *) bdaddr);
  230. }
  231. static struct {
  232. uint16_t compid;
  233. int (*write_bd_addr)(int dd, bdaddr_t *bdaddr);
  234. int (*reset_device)(int dd);
  235. } vendor[] = {
  236. { 0, ericsson_write_bd_addr, NULL },
  237. { 10, csr_write_bd_addr, csr_reset_device },
  238. { 13, ti_write_bd_addr, NULL },
  239. { 15, bcm_write_bd_addr, generic_reset_device },
  240. { 18, zeevo_write_bd_addr, NULL },
  241. { 48, st_write_bd_addr, generic_reset_device },
  242. { 57, ericsson_write_bd_addr, generic_reset_device },
  243. { 72, mrvl_write_bd_addr, generic_reset_device },
  244. { 65535, NULL, NULL },
  245. };
  246. static void usage(void)
  247. {
  248. printf("bdaddr - Utility for changing the Bluetooth device address\n\n");
  249. printf("Usage:\n"
  250. "\tbdaddr [-i <dev>] [-r] [-t] [new bdaddr]\n");
  251. }
  252. static struct option main_options[] = {
  253. { "device", 1, 0, 'i' },
  254. { "reset", 0, 0, 'r' },
  255. { "transient", 0, 0, 't' },
  256. { "help", 0, 0, 'h' },
  257. { 0, 0, 0, 0 }
  258. };
  259. int main(int argc, char *argv[])
  260. {
  261. struct hci_dev_info di;
  262. struct hci_version ver;
  263. bdaddr_t bdaddr;
  264. char addr[18], *comp;
  265. int i, dd, opt, dev = 0, reset = 0;
  266. bacpy(&bdaddr, BDADDR_ANY);
  267. while ((opt=getopt_long(argc, argv, "+i:rth", main_options, NULL)) != -1) {
  268. switch (opt) {
  269. case 'i':
  270. dev = hci_devid(optarg);
  271. if (dev < 0) {
  272. perror("Invalid device");
  273. exit(1);
  274. }
  275. break;
  276. case 'r':
  277. reset = 1;
  278. break;
  279. case 't':
  280. transient = 1;
  281. break;
  282. case 'h':
  283. default:
  284. usage();
  285. exit(0);
  286. }
  287. }
  288. argc -= optind;
  289. argv += optind;
  290. optind = 0;
  291. dd = hci_open_dev(dev);
  292. if (dd < 0) {
  293. fprintf(stderr, "Can't open device hci%d: %s (%d)\n",
  294. dev, strerror(errno), errno);
  295. exit(1);
  296. }
  297. if (hci_devinfo(dev, &di) < 0) {
  298. fprintf(stderr, "Can't get device info for hci%d: %s (%d)\n",
  299. dev, strerror(errno), errno);
  300. hci_close_dev(dd);
  301. exit(1);
  302. }
  303. if (hci_read_local_version(dd, &ver, 1000) < 0) {
  304. fprintf(stderr, "Can't read version info for hci%d: %s (%d)\n",
  305. dev, strerror(errno), errno);
  306. hci_close_dev(dd);
  307. exit(1);
  308. }
  309. if (!bacmp(&di.bdaddr, BDADDR_ANY)) {
  310. if (hci_read_bd_addr(dd, &bdaddr, 1000) < 0) {
  311. fprintf(stderr, "Can't read address for hci%d: %s (%d)\n",
  312. dev, strerror(errno), errno);
  313. hci_close_dev(dd);
  314. exit(1);
  315. }
  316. } else
  317. bacpy(&bdaddr, &di.bdaddr);
  318. printf("Manufacturer: %s (%d)\n",
  319. bt_compidtostr(ver.manufacturer), ver.manufacturer);
  320. comp = batocomp(&bdaddr);
  321. ba2str(&bdaddr, addr);
  322. printf("Device address: %s", addr);
  323. if (comp) {
  324. printf(" (%s)\n", comp);
  325. free(comp);
  326. } else
  327. printf("\n");
  328. if (argc < 1) {
  329. hci_close_dev(dd);
  330. exit(0);
  331. }
  332. str2ba(argv[0], &bdaddr);
  333. if (!bacmp(&bdaddr, BDADDR_ANY)) {
  334. hci_close_dev(dd);
  335. exit(0);
  336. }
  337. for (i = 0; vendor[i].compid != 65535; i++)
  338. if (ver.manufacturer == vendor[i].compid) {
  339. comp = batocomp(&bdaddr);
  340. ba2str(&bdaddr, addr);
  341. printf("New BD address: %s", addr);
  342. if (comp) {
  343. printf(" (%s)\n\n", comp);
  344. free(comp);
  345. } else
  346. printf("\n\n");
  347. if (vendor[i].write_bd_addr(dd, &bdaddr) < 0) {
  348. fprintf(stderr, "Can't write new address\n");
  349. hci_close_dev(dd);
  350. exit(1);
  351. }
  352. printf("Address changed - ");
  353. if (reset && vendor[i].reset_device) {
  354. if (vendor[i].reset_device(dd) < 0) {
  355. printf("Reset device manually\n");
  356. } else {
  357. ioctl(dd, HCIDEVRESET, dev);
  358. printf("Device reset successfully\n");
  359. }
  360. } else {
  361. printf("Reset device now\n");
  362. }
  363. //ioctl(dd, HCIDEVRESET, dev);
  364. //ioctl(dd, HCIDEVDOWN, dev);
  365. //ioctl(dd, HCIDEVUP, dev);
  366. hci_close_dev(dd);
  367. exit(0);
  368. }
  369. hci_close_dev(dd);
  370. printf("\n");
  371. fprintf(stderr, "Unsupported manufacturer\n");
  372. exit(1);
  373. }