hal-pan.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. // SPDX-License-Identifier: Apache-2.0
  2. /*
  3. * Copyright (C) 2013 Intel Corporation
  4. *
  5. */
  6. #define _GNU_SOURCE
  7. #include <stdbool.h>
  8. #include <stddef.h>
  9. #include <string.h>
  10. #include "hal-utils.h"
  11. #include "hal-log.h"
  12. #include "hal.h"
  13. #include "hal-msg.h"
  14. #include "hal-ipc.h"
  15. static const btpan_callbacks_t *cbs = NULL;
  16. static bool interface_ready(void)
  17. {
  18. return cbs != NULL;
  19. }
  20. static void handle_conn_state(void *buf, uint16_t len, int fd)
  21. {
  22. struct hal_ev_pan_conn_state *ev = buf;
  23. if (cbs->connection_state_cb)
  24. cbs->connection_state_cb(ev->state, ev->status,
  25. (bt_bdaddr_t *) ev->bdaddr,
  26. ev->local_role, ev->remote_role);
  27. }
  28. static void handle_ctrl_state(void *buf, uint16_t len, int fd)
  29. {
  30. struct hal_ev_pan_ctrl_state *ev = buf;
  31. #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
  32. if (cbs->control_state_cb)
  33. cbs->control_state_cb(ev->state, ev->local_role, ev->status,
  34. (char *)ev->name);
  35. #else
  36. /*
  37. * Callback declared in bt_pan.h is 'typedef void
  38. * (*btpan_control_state_callback)(btpan_control_state_t state,
  39. * bt_status_t error, int local_role, const char* ifname);
  40. * But PanService.Java defined it wrong way.
  41. * private void onControlStateChanged(int local_role, int state,
  42. * int error, String ifname).
  43. * First and third parameters are misplaced, so sending data according
  44. * to PanService.Java.
  45. */
  46. if (cbs->control_state_cb)
  47. cbs->control_state_cb(ev->local_role, ev->state, ev->status,
  48. (char *)ev->name);
  49. #endif
  50. }
  51. /*
  52. * handlers will be called from notification thread context,
  53. * index in table equals to 'opcode - HAL_MINIMUM_EVENT'
  54. */
  55. static const struct hal_ipc_handler ev_handlers[] = {
  56. /* HAL_EV_PAN_CTRL_STATE */
  57. { handle_ctrl_state, false, sizeof(struct hal_ev_pan_ctrl_state) },
  58. /* HAL_EV_PAN_CONN_STATE */
  59. { handle_conn_state, false, sizeof(struct hal_ev_pan_conn_state) },
  60. };
  61. static bt_status_t pan_enable(int local_role)
  62. {
  63. struct hal_cmd_pan_enable cmd;
  64. DBG("");
  65. if (!interface_ready())
  66. return BT_STATUS_NOT_READY;
  67. cmd.local_role = local_role;
  68. return hal_ipc_cmd(HAL_SERVICE_ID_PAN, HAL_OP_PAN_ENABLE,
  69. sizeof(cmd), &cmd, NULL, NULL, NULL);
  70. }
  71. static int pan_get_local_role(void)
  72. {
  73. struct hal_rsp_pan_get_role rsp;
  74. size_t len = sizeof(rsp);
  75. bt_status_t status;
  76. DBG("");
  77. if (!interface_ready())
  78. return BTPAN_ROLE_NONE;
  79. status = hal_ipc_cmd(HAL_SERVICE_ID_PAN, HAL_OP_PAN_GET_ROLE, 0, NULL,
  80. &len, &rsp, NULL);
  81. if (status != BT_STATUS_SUCCESS)
  82. return BTPAN_ROLE_NONE;
  83. return rsp.local_role;
  84. }
  85. static bt_status_t pan_connect(const bt_bdaddr_t *bd_addr, int local_role,
  86. int remote_role)
  87. {
  88. struct hal_cmd_pan_connect cmd;
  89. DBG("");
  90. if (!interface_ready())
  91. return BT_STATUS_NOT_READY;
  92. memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
  93. cmd.local_role = local_role;
  94. cmd.remote_role = remote_role;
  95. return hal_ipc_cmd(HAL_SERVICE_ID_PAN, HAL_OP_PAN_CONNECT,
  96. sizeof(cmd), &cmd, NULL, NULL, NULL);
  97. }
  98. static bt_status_t pan_disconnect(const bt_bdaddr_t *bd_addr)
  99. {
  100. struct hal_cmd_pan_disconnect cmd;
  101. DBG("");
  102. if (!interface_ready())
  103. return BT_STATUS_NOT_READY;
  104. memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr));
  105. return hal_ipc_cmd(HAL_SERVICE_ID_PAN, HAL_OP_PAN_DISCONNECT,
  106. sizeof(cmd), &cmd, NULL, NULL, NULL);
  107. }
  108. static bt_status_t pan_init(const btpan_callbacks_t *callbacks)
  109. {
  110. struct hal_cmd_register_module cmd;
  111. int ret;
  112. DBG("");
  113. if (interface_ready())
  114. return BT_STATUS_DONE;
  115. cbs = callbacks;
  116. hal_ipc_register(HAL_SERVICE_ID_PAN, ev_handlers,
  117. sizeof(ev_handlers)/sizeof(ev_handlers[0]));
  118. cmd.service_id = HAL_SERVICE_ID_PAN;
  119. cmd.mode = HAL_MODE_DEFAULT;
  120. cmd.max_clients = 1;
  121. ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
  122. sizeof(cmd), &cmd, NULL, NULL, NULL);
  123. if (ret != BT_STATUS_SUCCESS) {
  124. cbs = NULL;
  125. hal_ipc_unregister(HAL_SERVICE_ID_PAN);
  126. }
  127. return ret;
  128. }
  129. static void pan_cleanup(void)
  130. {
  131. struct hal_cmd_unregister_module cmd;
  132. DBG("");
  133. if (!interface_ready())
  134. return;
  135. cmd.service_id = HAL_SERVICE_ID_PAN;
  136. hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE,
  137. sizeof(cmd), &cmd, NULL, NULL, NULL);
  138. hal_ipc_unregister(HAL_SERVICE_ID_PAN);
  139. cbs = NULL;
  140. }
  141. static btpan_interface_t pan_if = {
  142. .size = sizeof(pan_if),
  143. .init = pan_init,
  144. .enable = pan_enable,
  145. .get_local_role = pan_get_local_role,
  146. .connect = pan_connect,
  147. .disconnect = pan_disconnect,
  148. .cleanup = pan_cleanup
  149. };
  150. btpan_interface_t *bt_get_pan_interface(void)
  151. {
  152. return &pan_if;
  153. }