| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- // SPDX-License-Identifier: LGPL-2.1-or-later
- /*
- *
- * BlueZ - Bluetooth protocol stack for Linux
- *
- * Copyright (C) 2014 Intel Corporation. All rights reserved.
- *
- *
- */
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
- #include <stdbool.h>
- #include <stdlib.h>
- #include <stdint.h>
- #include <glib.h>
- #include "lib/sdp.h"
- #include "lib/sdp_lib.h"
- #include "src/sdp-client.h"
- #include "ipc.h"
- #include "lib/bluetooth.h"
- #include "map-client.h"
- #include "src/log.h"
- #include "hal-msg.h"
- #include "ipc-common.h"
- #include "utils.h"
- #include "src/shared/util.h"
- static struct ipc *hal_ipc = NULL;
- static bdaddr_t adapter_addr;
- static int fill_mce_inst(void *buf, int32_t id, int32_t scn, int32_t msg_type,
- const void *name, uint8_t name_len)
- {
- struct hal_map_client_mas_instance *inst = buf;
- inst->id = id;
- inst->scn = scn;
- inst->msg_types = msg_type;
- inst->name_len = name_len;
- if (name_len)
- memcpy(inst->name, name, name_len);
- return sizeof(*inst) + name_len;
- }
- static void map_client_sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
- {
- uint8_t buf[IPC_MTU];
- struct hal_ev_map_client_remote_mas_instances *ev = (void *) buf;
- bdaddr_t *dst = data;
- sdp_list_t *list, *protos;
- uint8_t status;
- int32_t id, scn, msg_type, name_len, num_instances = 0;
- char *name;
- size_t size;
- size = sizeof(*ev);
- bdaddr2android(dst, &ev->bdaddr);
- if (err < 0) {
- error("mce: Unable to get SDP record: %s", strerror(-err));
- status = HAL_STATUS_FAILED;
- goto fail;
- }
- for (list = recs; list != NULL; list = list->next) {
- sdp_record_t *rec = list->data;
- sdp_data_t *data;
- data = sdp_data_get(rec, SDP_ATTR_MAS_INSTANCE_ID);
- if (!data) {
- error("mce: cannot get mas instance id");
- continue;
- }
- id = data->val.uint8;
- data = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY);
- if (!data) {
- error("mce: cannot get mas instance name");
- continue;
- }
- name = data->val.str;
- name_len = data->unitSize;
- data = sdp_data_get(rec, SDP_ATTR_SUPPORTED_MESSAGE_TYPES);
- if (!data) {
- error("mce: cannot get mas instance msg type");
- continue;
- }
- msg_type = data->val.uint8;
- if (sdp_get_access_protos(rec, &protos) < 0) {
- error("mce: cannot get mas instance sdp protocol list");
- continue;
- }
- scn = sdp_get_proto_port(protos, RFCOMM_UUID);
- sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL);
- sdp_list_free(protos, NULL);
- if (!scn) {
- error("mce: cannot get mas instance rfcomm channel");
- continue;
- }
- size += fill_mce_inst(buf + size, id, scn, msg_type, name,
- name_len);
- num_instances++;
- }
- status = HAL_STATUS_SUCCESS;
- fail:
- ev->num_instances = num_instances;
- ev->status = status;
- ipc_send_notif(hal_ipc, HAL_SERVICE_ID_MAP_CLIENT,
- HAL_EV_MAP_CLIENT_REMOTE_MAS_INSTANCES, size, buf);
- }
- static void handle_get_instances(const void *buf, uint16_t len)
- {
- const struct hal_cmd_map_client_get_instances *cmd = buf;
- uint8_t status;
- bdaddr_t *dst;
- uuid_t uuid;
- DBG("");
- dst = new0(bdaddr_t, 1);
- if (!dst) {
- error("mce: Fail to allocate cb data");
- status = HAL_STATUS_FAILED;
- goto failed;
- }
- android2bdaddr(&cmd->bdaddr, dst);
- sdp_uuid16_create(&uuid, MAP_MSE_SVCLASS_ID);
- if (bt_search_service(&adapter_addr, dst, &uuid,
- map_client_sdp_search_cb, dst, free, 0)) {
- error("mce: Failed to search SDP details");
- status = HAL_STATUS_FAILED;
- goto failed;
- }
- status = HAL_STATUS_SUCCESS;
- failed:
- ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_MAP_CLIENT,
- HAL_OP_MAP_CLIENT_GET_INSTANCES, status);
- }
- static const struct ipc_handler cmd_handlers[] = {
- /* HAL_OP_MAP_CLIENT_GET_INSTANCES */
- { handle_get_instances, false,
- sizeof(struct hal_cmd_map_client_get_instances) },
- };
- bool bt_map_client_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode)
- {
- DBG("");
- bacpy(&adapter_addr, addr);
- hal_ipc = ipc;
- ipc_register(hal_ipc, HAL_SERVICE_ID_MAP_CLIENT, cmd_handlers,
- G_N_ELEMENTS(cmd_handlers));
- return true;
- }
- void bt_map_client_unregister(void)
- {
- DBG("");
- ipc_unregister(hal_ipc, HAL_SERVICE_ID_MAP_CLIENT);
- hal_ipc = NULL;
- }
|