control.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2006-2010 Nokia Corporation
  7. * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
  8. * Copyright (C) 2011 Texas Instruments, Inc.
  9. *
  10. *
  11. */
  12. #ifdef HAVE_CONFIG_H
  13. #include <config.h>
  14. #endif
  15. #include <stdlib.h>
  16. #include <stdint.h>
  17. #include <errno.h>
  18. #include <unistd.h>
  19. #include <assert.h>
  20. #include <signal.h>
  21. #include <sys/types.h>
  22. #include <sys/stat.h>
  23. #include <fcntl.h>
  24. #include <glib.h>
  25. #include <dbus/dbus.h>
  26. #include "lib/bluetooth.h"
  27. #include "lib/sdp.h"
  28. #include "lib/sdp_lib.h"
  29. #include "lib/uuid.h"
  30. #include "gdbus/gdbus.h"
  31. #include "src/adapter.h"
  32. #include "src/device.h"
  33. #include "src/profile.h"
  34. #include "src/service.h"
  35. #include "src/log.h"
  36. #include "src/error.h"
  37. #include "src/sdpd.h"
  38. #include "src/uuid-helper.h"
  39. #include "src/dbus-common.h"
  40. #include "avctp.h"
  41. #include "control.h"
  42. #include "player.h"
  43. static GSList *devices = NULL;
  44. struct control {
  45. struct btd_device *dev;
  46. struct avctp *session;
  47. struct btd_service *target;
  48. struct btd_service *remote;
  49. unsigned int avctp_id;
  50. const char *player;
  51. };
  52. static void state_changed(struct btd_device *dev, avctp_state_t old_state,
  53. avctp_state_t new_state, int err,
  54. void *user_data)
  55. {
  56. struct control *control = user_data;
  57. DBusConnection *conn = btd_get_dbus_connection();
  58. const char *path = device_get_path(dev);
  59. switch (new_state) {
  60. case AVCTP_STATE_DISCONNECTED:
  61. control->session = NULL;
  62. control->player = NULL;
  63. g_dbus_emit_property_changed(conn, path,
  64. AUDIO_CONTROL_INTERFACE, "Connected");
  65. g_dbus_emit_property_changed(conn, path,
  66. AUDIO_CONTROL_INTERFACE, "Player");
  67. break;
  68. case AVCTP_STATE_CONNECTING:
  69. if (control->session)
  70. break;
  71. control->session = avctp_get(dev);
  72. break;
  73. case AVCTP_STATE_CONNECTED:
  74. g_dbus_emit_property_changed(conn, path,
  75. AUDIO_CONTROL_INTERFACE, "Connected");
  76. break;
  77. case AVCTP_STATE_BROWSING_CONNECTING:
  78. case AVCTP_STATE_BROWSING_CONNECTED:
  79. default:
  80. return;
  81. }
  82. }
  83. int control_connect(struct btd_service *service)
  84. {
  85. struct control *control = btd_service_get_user_data(service);
  86. if (control->session)
  87. return -EALREADY;
  88. control->session = avctp_connect(control->dev);
  89. if (!control->session)
  90. return -EIO;
  91. return 0;
  92. }
  93. int control_disconnect(struct btd_service *service)
  94. {
  95. struct control *control = btd_service_get_user_data(service);
  96. if (!control || !control->session)
  97. return -ENOTCONN;
  98. avctp_disconnect(control->session);
  99. return 0;
  100. }
  101. static DBusMessage *key_pressed(DBusConnection *conn, DBusMessage *msg,
  102. uint8_t op, bool hold, void *data)
  103. {
  104. struct control *control = data;
  105. int err;
  106. if (!control->session)
  107. return btd_error_not_connected(msg);
  108. if (!control->target)
  109. return btd_error_not_supported(msg);
  110. err = avctp_send_passthrough(control->session, op, hold);
  111. if (err < 0)
  112. return btd_error_failed(msg, strerror(-err));
  113. return dbus_message_new_method_return(msg);
  114. }
  115. static DBusMessage *control_volume_up(DBusConnection *conn, DBusMessage *msg,
  116. void *data)
  117. {
  118. return key_pressed(conn, msg, AVC_VOLUME_UP, false, data);
  119. }
  120. static DBusMessage *control_volume_down(DBusConnection *conn, DBusMessage *msg,
  121. void *data)
  122. {
  123. return key_pressed(conn, msg, AVC_VOLUME_DOWN, false, data);
  124. }
  125. static DBusMessage *control_play(DBusConnection *conn, DBusMessage *msg,
  126. void *data)
  127. {
  128. return key_pressed(conn, msg, AVC_PLAY, false, data);
  129. }
  130. static DBusMessage *control_pause(DBusConnection *conn, DBusMessage *msg,
  131. void *data)
  132. {
  133. return key_pressed(conn, msg, AVC_PAUSE, false, data);
  134. }
  135. static DBusMessage *control_stop(DBusConnection *conn, DBusMessage *msg,
  136. void *data)
  137. {
  138. return key_pressed(conn, msg, AVC_STOP, false, data);
  139. }
  140. static DBusMessage *control_next(DBusConnection *conn, DBusMessage *msg,
  141. void *data)
  142. {
  143. return key_pressed(conn, msg, AVC_FORWARD, false, data);
  144. }
  145. static DBusMessage *control_previous(DBusConnection *conn, DBusMessage *msg,
  146. void *data)
  147. {
  148. return key_pressed(conn, msg, AVC_BACKWARD, false, data);
  149. }
  150. static DBusMessage *control_fast_forward(DBusConnection *conn, DBusMessage *msg,
  151. void *data)
  152. {
  153. return key_pressed(conn, msg, AVC_FAST_FORWARD, true, data);
  154. }
  155. static DBusMessage *control_rewind(DBusConnection *conn, DBusMessage *msg,
  156. void *data)
  157. {
  158. return key_pressed(conn, msg, AVC_REWIND, true, data);
  159. }
  160. static gboolean control_property_get_connected(
  161. const GDBusPropertyTable *property,
  162. DBusMessageIter *iter, void *data)
  163. {
  164. struct control *control = data;
  165. dbus_bool_t value = (control->session != NULL);
  166. dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &value);
  167. return TRUE;
  168. }
  169. static gboolean control_player_exists(const GDBusPropertyTable *property,
  170. void *data)
  171. {
  172. struct control *control = data;
  173. return control->player != NULL;
  174. }
  175. static gboolean control_get_player(const GDBusPropertyTable *property,
  176. DBusMessageIter *iter, void *data)
  177. {
  178. struct control *control = data;
  179. if (!control->player)
  180. return FALSE;
  181. dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
  182. &control->player);
  183. return TRUE;
  184. }
  185. static const GDBusMethodTable control_methods[] = {
  186. { GDBUS_DEPRECATED_METHOD("Play", NULL, NULL, control_play) },
  187. { GDBUS_DEPRECATED_METHOD("Pause", NULL, NULL, control_pause) },
  188. { GDBUS_DEPRECATED_METHOD("Stop", NULL, NULL, control_stop) },
  189. { GDBUS_DEPRECATED_METHOD("Next", NULL, NULL, control_next) },
  190. { GDBUS_DEPRECATED_METHOD("Previous", NULL, NULL, control_previous) },
  191. { GDBUS_DEPRECATED_METHOD("VolumeUp", NULL, NULL, control_volume_up) },
  192. { GDBUS_DEPRECATED_METHOD("VolumeDown", NULL, NULL,
  193. control_volume_down) },
  194. { GDBUS_DEPRECATED_METHOD("FastForward", NULL, NULL,
  195. control_fast_forward) },
  196. { GDBUS_DEPRECATED_METHOD("Rewind", NULL, NULL, control_rewind) },
  197. { }
  198. };
  199. static const GDBusPropertyTable control_properties[] = {
  200. { "Connected", "b", control_property_get_connected },
  201. { "Player", "o", control_get_player, NULL, control_player_exists },
  202. { }
  203. };
  204. static void path_unregister(void *data)
  205. {
  206. struct control *control = data;
  207. DBG("Unregistered interface %s on path %s", AUDIO_CONTROL_INTERFACE,
  208. device_get_path(control->dev));
  209. if (control->session)
  210. avctp_disconnect(control->session);
  211. avctp_remove_state_cb(control->avctp_id);
  212. if (control->target) {
  213. btd_service_set_user_data(control->target, NULL);
  214. btd_service_unref(control->target);
  215. }
  216. if (control->remote) {
  217. btd_service_set_user_data(control->remote, NULL);
  218. btd_service_unref(control->remote);
  219. }
  220. devices = g_slist_remove(devices, control);
  221. g_free(control);
  222. }
  223. void control_unregister(struct btd_service *service)
  224. {
  225. struct btd_device *dev = btd_service_get_device(service);
  226. g_dbus_unregister_interface(btd_get_dbus_connection(),
  227. device_get_path(dev),
  228. AUDIO_CONTROL_INTERFACE);
  229. }
  230. static struct control *find_control(struct btd_device *dev)
  231. {
  232. GSList *l;
  233. for (l = devices; l; l = l->next) {
  234. struct control *control = l->data;
  235. if (control->dev == dev)
  236. return control;
  237. }
  238. return NULL;
  239. }
  240. static struct control *control_init(struct btd_service *service)
  241. {
  242. struct control *control;
  243. struct btd_device *dev = btd_service_get_device(service);
  244. control = find_control(dev);
  245. if (control != NULL)
  246. return control;
  247. control = g_new0(struct control, 1);
  248. if (!g_dbus_register_interface(btd_get_dbus_connection(),
  249. device_get_path(dev),
  250. AUDIO_CONTROL_INTERFACE,
  251. control_methods, NULL,
  252. control_properties, control,
  253. path_unregister)) {
  254. g_free(control);
  255. return NULL;
  256. }
  257. DBG("Registered interface %s on path %s", AUDIO_CONTROL_INTERFACE,
  258. device_get_path(dev));
  259. control->dev = dev;
  260. control->avctp_id = avctp_add_state_cb(dev, state_changed, control);
  261. devices = g_slist_prepend(devices, control);
  262. return control;
  263. }
  264. int control_init_target(struct btd_service *service)
  265. {
  266. struct control *control;
  267. control = control_init(service);
  268. if (control == NULL)
  269. return -EINVAL;
  270. control->target = btd_service_ref(service);
  271. btd_service_set_user_data(service, control);
  272. return 0;
  273. }
  274. int control_init_remote(struct btd_service *service)
  275. {
  276. struct control *control;
  277. control = control_init(service);
  278. if (control == NULL)
  279. return -EINVAL;
  280. control->remote = btd_service_ref(service);
  281. btd_service_set_user_data(service, control);
  282. return 0;
  283. }
  284. int control_set_player(struct btd_service *service, const char *path)
  285. {
  286. struct control *control = btd_service_get_user_data(service);
  287. if (!control->session)
  288. return -ENOTCONN;
  289. if (g_strcmp0(control->player, path) == 0)
  290. return -EALREADY;
  291. control->player = path;
  292. g_dbus_emit_property_changed(btd_get_dbus_connection(),
  293. device_get_path(control->dev),
  294. AUDIO_CONTROL_INTERFACE, "Player");
  295. return 0;
  296. }