hal-a2dp.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. // SPDX-License-Identifier: Apache-2.0
  2. /*
  3. * Copyright (C) 2013 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. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  34. struct hal_ev_a2dp_audio_config *ev = buf;
  35. if (cbs->audio_config_cb)
  36. cbs->audio_config_cb((bt_bdaddr_t *)(ev->bdaddr),
  37. ev->sample_rate, ev->channel_count);
  38. #endif
  39. }
  40. /*
  41. * handlers will be called from notification thread context,
  42. * index in table equals to 'opcode - HAL_MINIMUM_EVENT'
  43. */
  44. static const struct hal_ipc_handler ev_handlers[] = {
  45. /* HAL_EV_A2DP_CONN_STATE */
  46. { handle_conn_state, false, sizeof(struct hal_ev_a2dp_conn_state) },
  47. /* HAL_EV_A2DP_AUDIO_STATE */
  48. { handle_audio_state, false, sizeof(struct hal_ev_a2dp_audio_state) },
  49. /* HAL_EV_A2DP_AUDIO_CONFIG */
  50. { handle_audio_config, false, sizeof(struct hal_ev_a2dp_audio_config) },
  51. };
  52. static bt_status_t a2dp_connect(bt_bdaddr_t *bd_addr)
  53. {
  54. struct hal_cmd_a2dp_connect cmd;
  55. DBG("");
  56. if (!interface_ready())
  57. return BT_STATUS_NOT_READY;
  58. memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
  59. return hal_ipc_cmd(HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_CONNECT,
  60. sizeof(cmd), &cmd, NULL, NULL, NULL);
  61. }
  62. static bt_status_t disconnect(bt_bdaddr_t *bd_addr)
  63. {
  64. struct hal_cmd_a2dp_disconnect cmd;
  65. DBG("");
  66. if (!interface_ready())
  67. return BT_STATUS_NOT_READY;
  68. memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
  69. return hal_ipc_cmd(HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_DISCONNECT,
  70. sizeof(cmd), &cmd, NULL, NULL, NULL);
  71. }
  72. static bt_status_t init(btav_callbacks_t *callbacks)
  73. {
  74. struct hal_cmd_register_module cmd;
  75. int ret;
  76. DBG("");
  77. if (interface_ready())
  78. return BT_STATUS_DONE;
  79. cbs = callbacks;
  80. hal_ipc_register(HAL_SERVICE_ID_A2DP, ev_handlers,
  81. sizeof(ev_handlers)/sizeof(ev_handlers[0]));
  82. cmd.service_id = HAL_SERVICE_ID_A2DP;
  83. cmd.mode = HAL_MODE_DEFAULT;
  84. cmd.max_clients = 1;
  85. ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
  86. sizeof(cmd), &cmd, NULL, NULL, NULL);
  87. if (ret != BT_STATUS_SUCCESS) {
  88. cbs = NULL;
  89. hal_ipc_unregister(HAL_SERVICE_ID_A2DP);
  90. }
  91. return ret;
  92. }
  93. static void cleanup(void)
  94. {
  95. struct hal_cmd_unregister_module cmd;
  96. DBG("");
  97. if (!interface_ready())
  98. return;
  99. cmd.service_id = HAL_SERVICE_ID_A2DP;
  100. hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE,
  101. sizeof(cmd), &cmd, NULL, NULL, NULL);
  102. hal_ipc_unregister(HAL_SERVICE_ID_A2DP);
  103. cbs = NULL;
  104. }
  105. static btav_interface_t iface = {
  106. .size = sizeof(iface),
  107. .init = init,
  108. .connect = a2dp_connect,
  109. .disconnect = disconnect,
  110. .cleanup = cleanup
  111. };
  112. btav_interface_t *bt_get_a2dp_interface(void)
  113. {
  114. return &iface;
  115. }