sco.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2014 Intel Corporation. All rights reserved.
  7. *
  8. */
  9. #ifdef HAVE_CONFIG_H
  10. #include <config.h>
  11. #endif
  12. #include <stdlib.h>
  13. #include <stdbool.h>
  14. #include <errno.h>
  15. #include <glib.h>
  16. #include "lib/bluetooth.h"
  17. #include "btio/btio.h"
  18. #include "src/log.h"
  19. #include "src/shared/util.h"
  20. #include "sco.h"
  21. struct bt_sco {
  22. int ref_count;
  23. GIOChannel *server_io;
  24. GIOChannel *io;
  25. guint watch;
  26. bdaddr_t local_addr;
  27. bdaddr_t remote_addr;
  28. bt_sco_confirm_func_t confirm_cb;
  29. bt_sco_conn_func_t connect_cb;
  30. bt_sco_disconn_func_t disconnect_cb;
  31. };
  32. /* We support only one sco for the moment */
  33. static bool sco_in_use = false;
  34. static void clear_remote_address(struct bt_sco *sco)
  35. {
  36. memset(&sco->remote_addr, 0, sizeof(bdaddr_t));
  37. }
  38. static gboolean disconnect_watch(GIOChannel *chan, GIOCondition cond,
  39. gpointer user_data)
  40. {
  41. struct bt_sco *sco = user_data;
  42. g_io_channel_shutdown(sco->io, TRUE, NULL);
  43. g_io_channel_unref(sco->io);
  44. sco->io = NULL;
  45. DBG("");
  46. sco->watch = 0;
  47. if (sco->disconnect_cb)
  48. sco->disconnect_cb(&sco->remote_addr);
  49. clear_remote_address(sco);
  50. return FALSE;
  51. }
  52. static void connect_sco_cb(GIOChannel *chan, GError *err, gpointer user_data)
  53. {
  54. struct bt_sco *sco = user_data;
  55. DBG("");
  56. /* Lets unref connecting io */
  57. if (sco->io) {
  58. g_io_channel_unref(sco->io);
  59. sco->io = NULL;
  60. }
  61. if (err) {
  62. error("sco: Audio connect failed (%s)", err->message);
  63. /*
  64. * Connect_sco_cb is called only when connect_cb is in place
  65. * Therefore it is safe to call it
  66. */
  67. sco->connect_cb(SCO_STATUS_ERROR, &sco->remote_addr);
  68. clear_remote_address(sco);
  69. return;
  70. }
  71. g_io_channel_set_close_on_unref(chan, TRUE);
  72. sco->io = g_io_channel_ref(chan);
  73. sco->watch = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
  74. disconnect_watch, sco);
  75. /* It is safe to call it here */
  76. sco->connect_cb(SCO_STATUS_OK, &sco->remote_addr);
  77. }
  78. static void confirm_sco_cb(GIOChannel *chan, gpointer user_data)
  79. {
  80. char address[18];
  81. bdaddr_t bdaddr;
  82. GError *err = NULL;
  83. struct bt_sco *sco = user_data;
  84. uint16_t voice_settings;
  85. DBG("");
  86. bt_io_get(chan, &err,
  87. BT_IO_OPT_DEST, address,
  88. BT_IO_OPT_DEST_BDADDR, &bdaddr,
  89. BT_IO_OPT_INVALID);
  90. if (err) {
  91. error("sco: audio confirm failed (%s)", err->message);
  92. g_error_free(err);
  93. goto drop;
  94. }
  95. if (!sco->confirm_cb || !sco->connect_cb) {
  96. error("sco: Connect and/or confirm callback not registered ");
  97. goto drop;
  98. }
  99. /* Check if there is SCO */
  100. if (sco->io) {
  101. error("sco: SCO is in progress");
  102. goto drop;
  103. }
  104. if (!sco->confirm_cb(&bdaddr, &voice_settings)) {
  105. error("sco: Audio connection from %s rejected", address);
  106. goto drop;
  107. }
  108. bacpy(&sco->remote_addr, &bdaddr);
  109. DBG("Incoming SCO connection from %s, voice settings 0x%x", address,
  110. voice_settings);
  111. err = NULL;
  112. bt_io_set(chan, &err, BT_IO_OPT_VOICE, voice_settings,
  113. BT_IO_OPT_INVALID);
  114. if (err) {
  115. error("sco: Could not set voice settings (%s)", err->message);
  116. g_error_free(err);
  117. goto drop;
  118. }
  119. if (!bt_io_accept(chan, connect_sco_cb, sco, NULL, NULL)) {
  120. error("sco: Failed to accept audio connection");
  121. goto drop;
  122. }
  123. sco->io = g_io_channel_ref(chan);
  124. return;
  125. drop:
  126. g_io_channel_shutdown(chan, TRUE, NULL);
  127. }
  128. static bool sco_listen(struct bt_sco *sco)
  129. {
  130. GError *err = NULL;
  131. if (!sco)
  132. return false;
  133. sco->server_io = bt_io_listen(NULL, confirm_sco_cb, sco, NULL, &err,
  134. BT_IO_OPT_SOURCE_BDADDR,
  135. &sco->local_addr,
  136. BT_IO_OPT_INVALID);
  137. if (!sco->server_io) {
  138. error("sco: Failed to listen on SCO: %s", err->message);
  139. g_error_free(err);
  140. return false;
  141. }
  142. return true;
  143. }
  144. struct bt_sco *bt_sco_new(const bdaddr_t *local_bdaddr)
  145. {
  146. struct bt_sco *sco;
  147. if (!local_bdaddr)
  148. return NULL;
  149. /* For now we support only one SCO connection per time */
  150. if (sco_in_use)
  151. return NULL;
  152. sco = new0(struct bt_sco, 1);
  153. if (!sco)
  154. return NULL;
  155. bacpy(&sco->local_addr, local_bdaddr);
  156. if (!sco_listen(sco)) {
  157. free(sco);
  158. return NULL;
  159. }
  160. sco_in_use = true;
  161. return bt_sco_ref(sco);
  162. }
  163. struct bt_sco *bt_sco_ref(struct bt_sco *sco)
  164. {
  165. if (!sco)
  166. return NULL;
  167. __sync_fetch_and_add(&sco->ref_count, 1);
  168. return sco;
  169. }
  170. static void sco_free(struct bt_sco *sco)
  171. {
  172. if (sco->server_io) {
  173. g_io_channel_shutdown(sco->server_io, TRUE, NULL);
  174. g_io_channel_unref(sco->server_io);
  175. }
  176. if (sco->io) {
  177. g_io_channel_shutdown(sco->io, TRUE, NULL);
  178. g_io_channel_unref(sco->io);
  179. }
  180. g_free(sco);
  181. sco_in_use = false;
  182. }
  183. void bt_sco_unref(struct bt_sco *sco)
  184. {
  185. DBG("");
  186. if (!sco)
  187. return;
  188. if (__sync_sub_and_fetch(&sco->ref_count, 1))
  189. return;
  190. sco_free(sco);
  191. }
  192. bool bt_sco_connect(struct bt_sco *sco, const bdaddr_t *addr,
  193. uint16_t voice_settings)
  194. {
  195. GIOChannel *io;
  196. GError *gerr = NULL;
  197. DBG("");
  198. if (!sco || !sco->connect_cb || !addr) {
  199. error("sco: Incorrect parameters or missing connect_cb");
  200. return false;
  201. }
  202. /* Check if we have connection in progress */
  203. if (sco->io) {
  204. error("sco: Connection already in progress");
  205. return false;
  206. }
  207. io = bt_io_connect(connect_sco_cb, sco, NULL, &gerr,
  208. BT_IO_OPT_SOURCE_BDADDR, &sco->local_addr,
  209. BT_IO_OPT_DEST_BDADDR, addr,
  210. BT_IO_OPT_VOICE, voice_settings,
  211. BT_IO_OPT_INVALID);
  212. if (!io) {
  213. error("sco: unable to connect audio: %s", gerr->message);
  214. g_error_free(gerr);
  215. return false;
  216. }
  217. sco->io = io;
  218. bacpy(&sco->remote_addr, addr);
  219. return true;
  220. }
  221. void bt_sco_disconnect(struct bt_sco *sco)
  222. {
  223. if (!sco)
  224. return;
  225. if (sco->io)
  226. g_io_channel_shutdown(sco->io, TRUE, NULL);
  227. }
  228. bool bt_sco_get_fd_and_mtu(struct bt_sco *sco, int *fd, uint16_t *mtu)
  229. {
  230. GError *err;
  231. if (!sco->io || !fd || !mtu)
  232. return false;
  233. err = NULL;
  234. if (!bt_io_get(sco->io, &err, BT_IO_OPT_MTU, mtu, BT_IO_OPT_INVALID)) {
  235. error("Unable to get MTU: %s\n", err->message);
  236. g_clear_error(&err);
  237. return false;
  238. }
  239. *fd = g_io_channel_unix_get_fd(sco->io);
  240. return true;
  241. }
  242. void bt_sco_set_confirm_cb(struct bt_sco *sco,
  243. bt_sco_confirm_func_t func)
  244. {
  245. sco->confirm_cb = func;
  246. }
  247. void bt_sco_set_connect_cb(struct bt_sco *sco, bt_sco_conn_func_t func)
  248. {
  249. sco->connect_cb = func;
  250. }
  251. void bt_sco_set_disconnect_cb(struct bt_sco *sco,
  252. bt_sco_disconn_func_t func)
  253. {
  254. sco->disconnect_cb = func;
  255. }