hal-a2dp-sink.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. // SPDX-License-Identifier: Apache-2.0
  2. /*
  3. * Copyright (C) 2014 Intel Corporation
  4. *
  5. */
  6. #include <stdbool.h>
  7. #include <stddef.h>
  8. #include <string.h>
  9. #include "hal-log.h"
  10. #include "hal.h"
  11. #include "hal-msg.h"
  12. #include "hal-ipc.h"
  13. static const btav_callbacks_t *cbs = NULL;
  14. static bool interface_ready(void)
  15. {
  16. return cbs != NULL;
  17. }
  18. static void handle_conn_state(void *buf, uint16_t len, int fd)
  19. {
  20. struct hal_ev_a2dp_conn_state *ev = buf;
  21. if (cbs->connection_state_cb)
  22. cbs->connection_state_cb(ev->state,
  23. (bt_bdaddr_t *) (ev->bdaddr));
  24. }
  25. static void handle_audio_state(void *buf, uint16_t len, int fd)
  26. {
  27. struct hal_ev_a2dp_audio_state *ev = buf;
  28. if (cbs->audio_state_cb)
  29. cbs->audio_state_cb(ev->state, (bt_bdaddr_t *)(ev->bdaddr));
  30. }
  31. static void handle_audio_config(void *buf, uint16_t len, int fd)
  32. {
  33. struct hal_ev_a2dp_audio_config *ev = buf;
  34. if (cbs->audio_config_cb)
  35. cbs->audio_config_cb((bt_bdaddr_t *)(ev->bdaddr),
  36. ev->sample_rate, ev->channel_count);
  37. }
  38. /*
  39. * handlers will be called from notification thread context,
  40. * index in table equals to 'opcode - HAL_MINIMUM_EVENT'
  41. */
  42. static const struct hal_ipc_handler ev_handlers[] = {
  43. /* HAL_EV_A2DP_CONN_STATE */
  44. { handle_conn_state, false, sizeof(struct hal_ev_a2dp_conn_state) },
  45. /* HAL_EV_A2DP_AUDIO_STATE */
  46. { handle_audio_state, false, sizeof(struct hal_ev_a2dp_audio_state) },
  47. /* HAL_EV_A2DP_AUDIO_CONFIG */
  48. { handle_audio_config, false, sizeof(struct hal_ev_a2dp_audio_config) },
  49. };
  50. static bt_status_t a2dp_connect(bt_bdaddr_t *bd_addr)
  51. {
  52. struct hal_cmd_a2dp_connect cmd;
  53. DBG("");
  54. if (!interface_ready())
  55. return BT_STATUS_NOT_READY;
  56. memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
  57. return hal_ipc_cmd(HAL_SERVICE_ID_A2DP_SINK, HAL_OP_A2DP_CONNECT,
  58. sizeof(cmd), &cmd, NULL, NULL, NULL);
  59. }
  60. static bt_status_t disconnect(bt_bdaddr_t *bd_addr)
  61. {
  62. struct hal_cmd_a2dp_disconnect cmd;
  63. DBG("");
  64. if (!interface_ready())
  65. return BT_STATUS_NOT_READY;
  66. memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
  67. return hal_ipc_cmd(HAL_SERVICE_ID_A2DP_SINK, HAL_OP_A2DP_DISCONNECT,
  68. sizeof(cmd), &cmd, NULL, NULL, NULL);
  69. }
  70. static bt_status_t init(btav_callbacks_t *callbacks)
  71. {
  72. struct hal_cmd_register_module cmd;
  73. int ret;
  74. DBG("");
  75. if (interface_ready())
  76. return BT_STATUS_DONE;
  77. cbs = callbacks;
  78. hal_ipc_register(HAL_SERVICE_ID_A2DP_SINK, ev_handlers,
  79. sizeof(ev_handlers)/sizeof(ev_handlers[0]));
  80. cmd.service_id = HAL_SERVICE_ID_A2DP_SINK;
  81. cmd.mode = HAL_MODE_DEFAULT;
  82. cmd.max_clients = 1;
  83. ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
  84. sizeof(cmd), &cmd, NULL, NULL, NULL);
  85. if (ret != BT_STATUS_SUCCESS) {
  86. cbs = NULL;
  87. hal_ipc_unregister(HAL_SERVICE_ID_A2DP_SINK);
  88. }
  89. return ret;
  90. }
  91. static void cleanup(void)
  92. {
  93. struct hal_cmd_unregister_module cmd;
  94. DBG("");
  95. if (!interface_ready())
  96. return;
  97. cmd.service_id = HAL_SERVICE_ID_A2DP_SINK;
  98. hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE,
  99. sizeof(cmd), &cmd, NULL, NULL, NULL);
  100. hal_ipc_unregister(HAL_SERVICE_ID_A2DP_SINK);
  101. cbs = NULL;
  102. }
  103. static btav_interface_t iface = {
  104. .size = sizeof(iface),
  105. .init = init,
  106. .connect = a2dp_connect,
  107. .disconnect = disconnect,
  108. .cleanup = cleanup
  109. };
  110. btav_interface_t *bt_get_a2dp_sink_interface(void)
  111. {
  112. return &iface;
  113. }