3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2014 Intel Corporation. All rights reserved.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34 #include "lib/sdp_lib.h"
35 #include "src/sdp-client.h"
38 #include "lib/bluetooth.h"
39 #include "map-client.h"
42 #include "ipc-common.h"
44 #include "src/shared/util.h"
46 static struct ipc *hal_ipc = NULL;
47 static bdaddr_t adapter_addr;
49 static int fill_mce_inst(void *buf, int32_t id, int32_t scn, int32_t msg_type,
50 const void *name, uint8_t name_len)
52 struct hal_map_client_mas_instance *inst = buf;
56 inst->msg_types = msg_type;
57 inst->name_len = name_len;
60 memcpy(inst->name, name, name_len);
62 return sizeof(*inst) + name_len;
65 static void map_client_sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
68 struct hal_ev_map_client_remote_mas_instances *ev = (void *) buf;
70 sdp_list_t *list, *protos;
72 int32_t id, scn, msg_type, name_len, num_instances = 0;
77 bdaddr2android(dst, &ev->bdaddr);
80 error("mce: Unable to get SDP record: %s", strerror(-err));
81 status = HAL_STATUS_FAILED;
85 for (list = recs; list != NULL; list = list->next) {
86 sdp_record_t *rec = list->data;
89 data = sdp_data_get(rec, SDP_ATTR_MAS_INSTANCE_ID);
91 error("mce: cannot get mas instance id");
97 data = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY);
99 error("mce: cannot get mas instance name");
103 name = data->val.str;
104 name_len = data->unitSize;
106 data = sdp_data_get(rec, SDP_ATTR_SUPPORTED_MESSAGE_TYPES);
108 error("mce: cannot get mas instance msg type");
112 msg_type = data->val.uint8;
114 if (sdp_get_access_protos(rec, &protos) < 0) {
115 error("mce: cannot get mas instance sdp protocol list");
119 scn = sdp_get_proto_port(protos, RFCOMM_UUID);
121 sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL);
122 sdp_list_free(protos, NULL);
125 error("mce: cannot get mas instance rfcomm channel");
129 size += fill_mce_inst(buf + size, id, scn, msg_type, name,
134 status = HAL_STATUS_SUCCESS;
137 ev->num_instances = num_instances;
140 ipc_send_notif(hal_ipc, HAL_SERVICE_ID_MAP_CLIENT,
141 HAL_EV_MAP_CLIENT_REMOTE_MAS_INSTANCES, size, buf);
144 static void handle_get_instances(const void *buf, uint16_t len)
146 const struct hal_cmd_map_client_get_instances *cmd = buf;
153 dst = new0(bdaddr_t, 1);
155 error("mce: Fail to allocate cb data");
156 status = HAL_STATUS_FAILED;
160 android2bdaddr(&cmd->bdaddr, dst);
161 sdp_uuid16_create(&uuid, MAP_MSE_SVCLASS_ID);
163 if (bt_search_service(&adapter_addr, dst, &uuid,
164 map_client_sdp_search_cb, dst, free, 0)) {
165 error("mce: Failed to search SDP details");
166 status = HAL_STATUS_FAILED;
170 status = HAL_STATUS_SUCCESS;
173 ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_MAP_CLIENT,
174 HAL_OP_MAP_CLIENT_GET_INSTANCES, status);
177 static const struct ipc_handler cmd_handlers[] = {
178 /* HAL_OP_MAP_CLIENT_GET_INSTANCES */
179 { handle_get_instances, false,
180 sizeof(struct hal_cmd_map_client_get_instances) },
183 bool bt_map_client_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode)
187 bacpy(&adapter_addr, addr);
191 ipc_register(hal_ipc, HAL_SERVICE_ID_MAP_CLIENT, cmd_handlers,
192 G_N_ELEMENTS(cmd_handlers));
197 void bt_map_client_unregister(void)
201 ipc_unregister(hal_ipc, HAL_SERVICE_ID_MAP_CLIENT);