map-client.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. // SPDX-License-Identifier: LGPL-2.1-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2014 Intel Corporation. All rights reserved.
  7. *
  8. *
  9. */
  10. #ifdef HAVE_CONFIG_H
  11. #include <config.h>
  12. #endif
  13. #include <stdbool.h>
  14. #include <stdlib.h>
  15. #include <stdint.h>
  16. #include <glib.h>
  17. #include "lib/sdp.h"
  18. #include "lib/sdp_lib.h"
  19. #include "src/sdp-client.h"
  20. #include "ipc.h"
  21. #include "lib/bluetooth.h"
  22. #include "map-client.h"
  23. #include "src/log.h"
  24. #include "hal-msg.h"
  25. #include "ipc-common.h"
  26. #include "utils.h"
  27. #include "src/shared/util.h"
  28. static struct ipc *hal_ipc = NULL;
  29. static bdaddr_t adapter_addr;
  30. static int fill_mce_inst(void *buf, int32_t id, int32_t scn, int32_t msg_type,
  31. const void *name, uint8_t name_len)
  32. {
  33. struct hal_map_client_mas_instance *inst = buf;
  34. inst->id = id;
  35. inst->scn = scn;
  36. inst->msg_types = msg_type;
  37. inst->name_len = name_len;
  38. if (name_len)
  39. memcpy(inst->name, name, name_len);
  40. return sizeof(*inst) + name_len;
  41. }
  42. static void map_client_sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
  43. {
  44. uint8_t buf[IPC_MTU];
  45. struct hal_ev_map_client_remote_mas_instances *ev = (void *) buf;
  46. bdaddr_t *dst = data;
  47. sdp_list_t *list, *protos;
  48. uint8_t status;
  49. int32_t id, scn, msg_type, name_len, num_instances = 0;
  50. char *name;
  51. size_t size;
  52. size = sizeof(*ev);
  53. bdaddr2android(dst, &ev->bdaddr);
  54. if (err < 0) {
  55. error("mce: Unable to get SDP record: %s", strerror(-err));
  56. status = HAL_STATUS_FAILED;
  57. goto fail;
  58. }
  59. for (list = recs; list != NULL; list = list->next) {
  60. sdp_record_t *rec = list->data;
  61. sdp_data_t *data;
  62. data = sdp_data_get(rec, SDP_ATTR_MAS_INSTANCE_ID);
  63. if (!data) {
  64. error("mce: cannot get mas instance id");
  65. continue;
  66. }
  67. id = data->val.uint8;
  68. data = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY);
  69. if (!data) {
  70. error("mce: cannot get mas instance name");
  71. continue;
  72. }
  73. name = data->val.str;
  74. name_len = data->unitSize;
  75. data = sdp_data_get(rec, SDP_ATTR_SUPPORTED_MESSAGE_TYPES);
  76. if (!data) {
  77. error("mce: cannot get mas instance msg type");
  78. continue;
  79. }
  80. msg_type = data->val.uint8;
  81. if (sdp_get_access_protos(rec, &protos) < 0) {
  82. error("mce: cannot get mas instance sdp protocol list");
  83. continue;
  84. }
  85. scn = sdp_get_proto_port(protos, RFCOMM_UUID);
  86. sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL);
  87. sdp_list_free(protos, NULL);
  88. if (!scn) {
  89. error("mce: cannot get mas instance rfcomm channel");
  90. continue;
  91. }
  92. size += fill_mce_inst(buf + size, id, scn, msg_type, name,
  93. name_len);
  94. num_instances++;
  95. }
  96. status = HAL_STATUS_SUCCESS;
  97. fail:
  98. ev->num_instances = num_instances;
  99. ev->status = status;
  100. ipc_send_notif(hal_ipc, HAL_SERVICE_ID_MAP_CLIENT,
  101. HAL_EV_MAP_CLIENT_REMOTE_MAS_INSTANCES, size, buf);
  102. }
  103. static void handle_get_instances(const void *buf, uint16_t len)
  104. {
  105. const struct hal_cmd_map_client_get_instances *cmd = buf;
  106. uint8_t status;
  107. bdaddr_t *dst;
  108. uuid_t uuid;
  109. DBG("");
  110. dst = new0(bdaddr_t, 1);
  111. if (!dst) {
  112. error("mce: Fail to allocate cb data");
  113. status = HAL_STATUS_FAILED;
  114. goto failed;
  115. }
  116. android2bdaddr(&cmd->bdaddr, dst);
  117. sdp_uuid16_create(&uuid, MAP_MSE_SVCLASS_ID);
  118. if (bt_search_service(&adapter_addr, dst, &uuid,
  119. map_client_sdp_search_cb, dst, free, 0)) {
  120. error("mce: Failed to search SDP details");
  121. status = HAL_STATUS_FAILED;
  122. goto failed;
  123. }
  124. status = HAL_STATUS_SUCCESS;
  125. failed:
  126. ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_MAP_CLIENT,
  127. HAL_OP_MAP_CLIENT_GET_INSTANCES, status);
  128. }
  129. static const struct ipc_handler cmd_handlers[] = {
  130. /* HAL_OP_MAP_CLIENT_GET_INSTANCES */
  131. { handle_get_instances, false,
  132. sizeof(struct hal_cmd_map_client_get_instances) },
  133. };
  134. bool bt_map_client_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode)
  135. {
  136. DBG("");
  137. bacpy(&adapter_addr, addr);
  138. hal_ipc = ipc;
  139. ipc_register(hal_ipc, HAL_SERVICE_ID_MAP_CLIENT, cmd_handlers,
  140. G_N_ELEMENTS(cmd_handlers));
  141. return true;
  142. }
  143. void bt_map_client_unregister(void)
  144. {
  145. DBG("");
  146. ipc_unregister(hal_ipc, HAL_SERVICE_ID_MAP_CLIENT);
  147. hal_ipc = NULL;
  148. }