hciemu.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673
  1. // SPDX-License-Identifier: LGPL-2.1-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2012-2014 Intel Corporation. All rights reserved.
  7. *
  8. *
  9. */
  10. #ifdef HAVE_CONFIG_H
  11. #include <config.h>
  12. #endif
  13. #define _GNU_SOURCE
  14. #include <stdio.h>
  15. #include <fcntl.h>
  16. #include <unistd.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <stdbool.h>
  20. #include <errno.h>
  21. #include <sys/socket.h>
  22. #include <glib.h>
  23. #include "lib/bluetooth.h"
  24. #include "lib/hci.h"
  25. #include "monitor/bt.h"
  26. #include "emulator/btdev.h"
  27. #include "emulator/bthost.h"
  28. #include "src/shared/util.h"
  29. #include "src/shared/queue.h"
  30. #include "emulator/hciemu.h"
  31. struct hciemu_client {
  32. struct bthost *host;
  33. struct btdev *dev;
  34. guint start_source;
  35. guint host_source;
  36. guint source;
  37. };
  38. struct hciemu {
  39. int ref_count;
  40. enum btdev_type btdev_type;
  41. struct btdev *dev;
  42. struct queue *clients;
  43. guint source;
  44. struct queue *post_command_hooks;
  45. char bdaddr_str[18];
  46. hciemu_debug_func_t debug_callback;
  47. hciemu_destroy_func_t debug_destroy;
  48. void *debug_data;
  49. };
  50. struct hciemu_command_hook {
  51. hciemu_command_func_t function;
  52. void *user_data;
  53. };
  54. static void destroy_command_hook(void *data)
  55. {
  56. struct hciemu_command_hook *hook = data;
  57. free(hook);
  58. }
  59. struct run_data {
  60. uint16_t opcode;
  61. const void *data;
  62. uint8_t len;
  63. };
  64. static void run_command_hook(void *data, void *user_data)
  65. {
  66. struct hciemu_command_hook *hook = data;
  67. struct run_data *run_data = user_data;
  68. if (hook->function)
  69. hook->function(run_data->opcode, run_data->data,
  70. run_data->len, hook->user_data);
  71. }
  72. static void central_command_callback(uint16_t opcode,
  73. const void *data, uint8_t len,
  74. btdev_callback callback, void *user_data)
  75. {
  76. struct hciemu *hciemu = user_data;
  77. struct run_data run_data = { .opcode = opcode,
  78. .data = data, .len = len };
  79. btdev_command_default(callback);
  80. queue_foreach(hciemu->post_command_hooks, run_command_hook, &run_data);
  81. }
  82. static void client_command_callback(uint16_t opcode,
  83. const void *data, uint8_t len,
  84. btdev_callback callback, void *user_data)
  85. {
  86. btdev_command_default(callback);
  87. }
  88. static void writev_callback(const struct iovec *iov, int iovlen,
  89. void *user_data)
  90. {
  91. GIOChannel *channel = user_data;
  92. ssize_t written;
  93. int fd;
  94. fd = g_io_channel_unix_get_fd(channel);
  95. written = writev(fd, iov, iovlen);
  96. if (written < 0)
  97. return;
  98. }
  99. static gboolean receive_bthost(GIOChannel *channel, GIOCondition condition,
  100. gpointer user_data)
  101. {
  102. struct bthost *bthost = user_data;
  103. unsigned char buf[4096];
  104. ssize_t len;
  105. int fd;
  106. if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP))
  107. return FALSE;
  108. fd = g_io_channel_unix_get_fd(channel);
  109. len = read(fd, buf, sizeof(buf));
  110. if (len < 0)
  111. return FALSE;
  112. bthost_receive_h4(bthost, buf, len);
  113. return TRUE;
  114. }
  115. static guint create_source_bthost(int fd, struct bthost *bthost)
  116. {
  117. GIOChannel *channel;
  118. guint source;
  119. channel = g_io_channel_unix_new(fd);
  120. g_io_channel_set_close_on_unref(channel, TRUE);
  121. g_io_channel_set_encoding(channel, NULL, NULL);
  122. g_io_channel_set_buffered(channel, FALSE);
  123. bthost_set_send_handler(bthost, writev_callback, channel);
  124. source = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT,
  125. G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
  126. receive_bthost, bthost, NULL);
  127. g_io_channel_unref(channel);
  128. return source;
  129. }
  130. static gboolean receive_btdev(GIOChannel *channel, GIOCondition condition,
  131. gpointer user_data)
  132. {
  133. struct btdev *btdev = user_data;
  134. unsigned char buf[4096];
  135. ssize_t len;
  136. int fd;
  137. if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP))
  138. return FALSE;
  139. fd = g_io_channel_unix_get_fd(channel);
  140. len = read(fd, buf, sizeof(buf));
  141. if (len < 0) {
  142. if (errno == EAGAIN || errno == EINTR)
  143. return TRUE;
  144. return FALSE;
  145. }
  146. if (len < 1)
  147. return FALSE;
  148. switch (buf[0]) {
  149. case BT_H4_CMD_PKT:
  150. case BT_H4_ACL_PKT:
  151. case BT_H4_SCO_PKT:
  152. btdev_receive_h4(btdev, buf, len);
  153. break;
  154. }
  155. return TRUE;
  156. }
  157. static guint create_source_btdev(int fd, struct btdev *btdev)
  158. {
  159. GIOChannel *channel;
  160. guint source;
  161. channel = g_io_channel_unix_new(fd);
  162. g_io_channel_set_close_on_unref(channel, TRUE);
  163. g_io_channel_set_encoding(channel, NULL, NULL);
  164. g_io_channel_set_buffered(channel, FALSE);
  165. btdev_set_send_handler(btdev, writev_callback, channel);
  166. source = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT,
  167. G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
  168. receive_btdev, btdev, NULL);
  169. g_io_channel_unref(channel);
  170. return source;
  171. }
  172. static bool create_vhci(struct hciemu *hciemu)
  173. {
  174. struct btdev *btdev;
  175. uint8_t create_req[2];
  176. ssize_t written;
  177. int fd;
  178. btdev = btdev_create(hciemu->btdev_type, 0x00);
  179. if (!btdev)
  180. return false;
  181. btdev_set_command_handler(btdev, central_command_callback, hciemu);
  182. fd = open("/dev/vhci", O_RDWR | O_NONBLOCK | O_CLOEXEC);
  183. if (fd < 0) {
  184. perror("Opening /dev/vhci failed");
  185. btdev_destroy(btdev);
  186. return false;
  187. }
  188. create_req[0] = HCI_VENDOR_PKT;
  189. create_req[1] = HCI_PRIMARY;
  190. written = write(fd, create_req, sizeof(create_req));
  191. if (written < 0) {
  192. close(fd);
  193. btdev_destroy(btdev);
  194. return false;
  195. }
  196. hciemu->dev = btdev;
  197. hciemu->source = create_source_btdev(fd, btdev);
  198. return true;
  199. }
  200. struct hciemu_client *hciemu_get_client(struct hciemu *hciemu, int num)
  201. {
  202. const struct queue_entry *entry;
  203. if (!hciemu)
  204. return NULL;
  205. for (entry = queue_get_entries(hciemu->clients); entry;
  206. entry = entry->next, num--) {
  207. if (!num)
  208. return entry->data;
  209. }
  210. return NULL;
  211. }
  212. struct bthost *hciemu_client_host(struct hciemu_client *client)
  213. {
  214. if (!client)
  215. return NULL;
  216. return client->host;
  217. }
  218. struct bthost *hciemu_client_get_host(struct hciemu *hciemu)
  219. {
  220. struct hciemu_client *client;
  221. if (!hciemu)
  222. return NULL;
  223. client = hciemu_get_client(hciemu, 0);
  224. return hciemu_client_host(client);
  225. }
  226. static gboolean start_host(gpointer user_data)
  227. {
  228. struct hciemu_client *client = user_data;
  229. client->start_source = 0;
  230. bthost_start(client->host);
  231. return FALSE;
  232. }
  233. static void hciemu_client_destroy(void *data)
  234. {
  235. struct hciemu_client *client = data;
  236. if (client->start_source)
  237. g_source_remove(client->start_source);
  238. g_source_remove(client->host_source);
  239. g_source_remove(client->source);
  240. bthost_destroy(client->host);
  241. btdev_destroy(client->dev);
  242. free(client);
  243. }
  244. static struct hciemu_client *hciemu_client_new(struct hciemu *hciemu,
  245. uint8_t id)
  246. {
  247. struct hciemu_client *client;
  248. int sv[2];
  249. client = new0(struct hciemu_client, 1);
  250. if (!client)
  251. return NULL;
  252. client->dev = btdev_create(hciemu->btdev_type, id++);
  253. if (!client->dev) {
  254. free(client);
  255. return NULL;
  256. }
  257. client->host = bthost_create();
  258. if (!client->host) {
  259. btdev_destroy(client->dev);
  260. free(client);
  261. return NULL;
  262. }
  263. btdev_set_command_handler(client->dev, client_command_callback, client);
  264. if (socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC,
  265. 0, sv) < 0) {
  266. bthost_destroy(client->host);
  267. btdev_destroy(client->dev);
  268. return NULL;
  269. }
  270. client->source = create_source_btdev(sv[0], client->dev);
  271. client->host_source = create_source_bthost(sv[1], client->host);
  272. client->start_source = g_idle_add(start_host, client);
  273. return client;
  274. }
  275. struct hciemu *hciemu_new_num(enum hciemu_type type, uint8_t num)
  276. {
  277. struct hciemu *hciemu;
  278. int i;
  279. if (!num)
  280. return NULL;
  281. hciemu = new0(struct hciemu, 1);
  282. if (!hciemu)
  283. return NULL;
  284. switch (type) {
  285. case HCIEMU_TYPE_BREDRLE:
  286. hciemu->btdev_type = BTDEV_TYPE_BREDRLE;
  287. break;
  288. case HCIEMU_TYPE_BREDR:
  289. hciemu->btdev_type = BTDEV_TYPE_BREDR;
  290. break;
  291. case HCIEMU_TYPE_LE:
  292. hciemu->btdev_type = BTDEV_TYPE_LE;
  293. break;
  294. case HCIEMU_TYPE_LEGACY:
  295. hciemu->btdev_type = BTDEV_TYPE_BREDR20;
  296. break;
  297. case HCIEMU_TYPE_BREDRLE50:
  298. hciemu->btdev_type = BTDEV_TYPE_BREDRLE50;
  299. break;
  300. case HCIEMU_TYPE_BREDRLE52:
  301. hciemu->btdev_type = BTDEV_TYPE_BREDRLE52;
  302. break;
  303. default:
  304. return NULL;
  305. }
  306. hciemu->post_command_hooks = queue_new();
  307. if (!hciemu->post_command_hooks) {
  308. free(hciemu);
  309. return NULL;
  310. }
  311. if (!create_vhci(hciemu)) {
  312. queue_destroy(hciemu->post_command_hooks, NULL);
  313. free(hciemu);
  314. return NULL;
  315. }
  316. hciemu->clients = queue_new();
  317. for (i = 0; i < num; i++) {
  318. struct hciemu_client *client = hciemu_client_new(hciemu, i);
  319. if (!client) {
  320. queue_destroy(hciemu->clients, hciemu_client_destroy);
  321. break;
  322. }
  323. queue_push_tail(hciemu->clients, client);
  324. }
  325. return hciemu_ref(hciemu);
  326. }
  327. struct hciemu *hciemu_new(enum hciemu_type type)
  328. {
  329. return hciemu_new_num(type, 1);
  330. }
  331. struct hciemu *hciemu_ref(struct hciemu *hciemu)
  332. {
  333. if (!hciemu)
  334. return NULL;
  335. __sync_fetch_and_add(&hciemu->ref_count, 1);
  336. return hciemu;
  337. }
  338. void hciemu_unref(struct hciemu *hciemu)
  339. {
  340. if (!hciemu)
  341. return;
  342. if (__sync_sub_and_fetch(&hciemu->ref_count, 1))
  343. return;
  344. queue_destroy(hciemu->post_command_hooks, destroy_command_hook);
  345. queue_destroy(hciemu->clients, hciemu_client_destroy);
  346. g_source_remove(hciemu->source);
  347. btdev_destroy(hciemu->dev);
  348. free(hciemu);
  349. }
  350. static void bthost_print(const char *str, void *user_data)
  351. {
  352. struct hciemu *hciemu = user_data;
  353. util_debug(hciemu->debug_callback, hciemu->debug_data,
  354. "bthost: %s", str);
  355. }
  356. static void btdev_central_debug(const char *str, void *user_data)
  357. {
  358. struct hciemu *hciemu = user_data;
  359. util_debug(hciemu->debug_callback, hciemu->debug_data,
  360. "btdev: %s", str);
  361. }
  362. static void btdev_client_debug(const char *str, void *user_data)
  363. {
  364. struct hciemu *hciemu = user_data;
  365. util_debug(hciemu->debug_callback, hciemu->debug_data,
  366. "btdev[bthost]: %s", str);
  367. }
  368. static void hciemu_client_set_debug(void *data, void *user_data)
  369. {
  370. struct hciemu_client *client = data;
  371. struct hciemu *hciemu = user_data;
  372. btdev_set_debug(client->dev, btdev_client_debug, hciemu, NULL);
  373. bthost_set_debug(client->host, bthost_print, hciemu, NULL);
  374. }
  375. bool hciemu_set_debug(struct hciemu *hciemu, hciemu_debug_func_t callback,
  376. void *user_data, hciemu_destroy_func_t destroy)
  377. {
  378. if (!hciemu)
  379. return false;
  380. if (hciemu->debug_destroy)
  381. hciemu->debug_destroy(hciemu->debug_data);
  382. hciemu->debug_callback = callback;
  383. hciemu->debug_destroy = destroy;
  384. hciemu->debug_data = user_data;
  385. btdev_set_debug(hciemu->dev, btdev_central_debug, hciemu, NULL);
  386. queue_foreach(hciemu->clients, hciemu_client_set_debug, hciemu);
  387. return true;
  388. }
  389. const char *hciemu_get_address(struct hciemu *hciemu)
  390. {
  391. const uint8_t *addr;
  392. if (!hciemu || !hciemu->dev)
  393. return NULL;
  394. addr = btdev_get_bdaddr(hciemu->dev);
  395. sprintf(hciemu->bdaddr_str, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
  396. addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]);
  397. return hciemu->bdaddr_str;
  398. }
  399. uint8_t *hciemu_get_features(struct hciemu *hciemu)
  400. {
  401. if (!hciemu || !hciemu->dev)
  402. return NULL;
  403. return btdev_get_features(hciemu->dev);
  404. }
  405. const uint8_t *hciemu_get_central_bdaddr(struct hciemu *hciemu)
  406. {
  407. if (!hciemu || !hciemu->dev)
  408. return NULL;
  409. return btdev_get_bdaddr(hciemu->dev);
  410. }
  411. const uint8_t *hciemu_client_bdaddr(struct hciemu_client *client)
  412. {
  413. if (!client)
  414. return NULL;
  415. return btdev_get_bdaddr(client->dev);
  416. }
  417. const uint8_t *hciemu_get_client_bdaddr(struct hciemu *hciemu)
  418. {
  419. struct hciemu_client *client;
  420. if (!hciemu)
  421. return NULL;
  422. client = hciemu_get_client(hciemu, 0);
  423. return hciemu_client_bdaddr(client);
  424. }
  425. uint8_t hciemu_get_central_scan_enable(struct hciemu *hciemu)
  426. {
  427. if (!hciemu || !hciemu->dev)
  428. return 0;
  429. return btdev_get_scan_enable(hciemu->dev);
  430. }
  431. uint8_t hciemu_get_central_le_scan_enable(struct hciemu *hciemu)
  432. {
  433. if (!hciemu || !hciemu->dev)
  434. return 0;
  435. return btdev_get_le_scan_enable(hciemu->dev);
  436. }
  437. void hciemu_set_central_le_states(struct hciemu *hciemu,
  438. const uint8_t *le_states)
  439. {
  440. if (!hciemu || !hciemu->dev)
  441. return;
  442. btdev_set_le_states(hciemu->dev, le_states);
  443. }
  444. bool hciemu_add_central_post_command_hook(struct hciemu *hciemu,
  445. hciemu_command_func_t function, void *user_data)
  446. {
  447. struct hciemu_command_hook *hook;
  448. if (!hciemu)
  449. return false;
  450. hook = new0(struct hciemu_command_hook, 1);
  451. if (!hook)
  452. return false;
  453. hook->function = function;
  454. hook->user_data = user_data;
  455. if (!queue_push_tail(hciemu->post_command_hooks, hook)) {
  456. free(hook);
  457. return false;
  458. }
  459. return true;
  460. }
  461. bool hciemu_clear_central_post_command_hooks(struct hciemu *hciemu)
  462. {
  463. if (!hciemu)
  464. return false;
  465. queue_remove_all(hciemu->post_command_hooks,
  466. NULL, NULL, destroy_command_hook);
  467. return true;
  468. }
  469. int hciemu_add_hook(struct hciemu *hciemu, enum hciemu_hook_type type,
  470. uint16_t opcode, hciemu_hook_func_t function,
  471. void *user_data)
  472. {
  473. enum btdev_hook_type hook_type;
  474. if (!hciemu)
  475. return -1;
  476. switch (type) {
  477. case HCIEMU_HOOK_PRE_CMD:
  478. hook_type = BTDEV_HOOK_PRE_CMD;
  479. break;
  480. case HCIEMU_HOOK_POST_CMD:
  481. hook_type = BTDEV_HOOK_POST_CMD;
  482. break;
  483. case HCIEMU_HOOK_PRE_EVT:
  484. hook_type = BTDEV_HOOK_PRE_EVT;
  485. break;
  486. case HCIEMU_HOOK_POST_EVT:
  487. hook_type = BTDEV_HOOK_POST_EVT;
  488. break;
  489. default:
  490. return -1;
  491. }
  492. return btdev_add_hook(hciemu->dev, hook_type, opcode, function,
  493. user_data);
  494. }
  495. bool hciemu_del_hook(struct hciemu *hciemu, enum hciemu_hook_type type,
  496. uint16_t opcode)
  497. {
  498. enum btdev_hook_type hook_type;
  499. if (!hciemu)
  500. return false;
  501. switch (type) {
  502. case HCIEMU_HOOK_PRE_CMD:
  503. hook_type = BTDEV_HOOK_PRE_CMD;
  504. break;
  505. case HCIEMU_HOOK_POST_CMD:
  506. hook_type = BTDEV_HOOK_POST_CMD;
  507. break;
  508. case HCIEMU_HOOK_PRE_EVT:
  509. hook_type = BTDEV_HOOK_PRE_EVT;
  510. break;
  511. case HCIEMU_HOOK_POST_EVT:
  512. hook_type = BTDEV_HOOK_POST_EVT;
  513. break;
  514. default:
  515. return false;
  516. }
  517. return btdev_del_hook(hciemu->dev, hook_type, opcode);
  518. }