Home | History | Annotate | Download | only in health
      1 /*
      2  *
      3  *  BlueZ - Bluetooth protocol stack for Linux
      4  *
      5  *  Copyright (C) 2010 GSyC/LibreSoft, Universidad Rey Juan Carlos.
      6  *  Authors:
      7  *  Santiago Carot Nemesio <sancane at gmail.com>
      8  *  Jose Antonio Santos-Cadenas <santoscadenas at gmail.com>
      9  *
     10  *  This program is free software; you can redistribute it and/or modify
     11  *  it under the terms of the GNU General Public License as published by
     12  *  the Free Software Foundation; either version 2 of the License, or
     13  *  (at your option) any later version.
     14  *
     15  *  This program is distributed in the hope that it will be useful,
     16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18  *  GNU General Public License for more details.
     19  *
     20  *  You should have received a copy of the GNU General Public License
     21  *  along with this program; if not, write to the Free Software
     22  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     23  *
     24  */
     25 
     26 #include <gdbus.h>
     27 
     28 #include <adapter.h>
     29 #include <device.h>
     30 #include <stdint.h>
     31 #include <hdp_types.h>
     32 #include <hdp_util.h>
     33 #include <mcap.h>
     34 #include <hdp.h>
     35 
     36 #include <sdpd.h>
     37 #include <bluetooth/sdp_lib.h>
     38 #include <glib-helper.h>
     39 
     40 #include <btio.h>
     41 #include <mcap_lib.h>
     42 
     43 #include <log.h>
     44 
     45 typedef gboolean (*parse_item_f)(DBusMessageIter *iter, gpointer user_data,
     46 								GError **err);
     47 
     48 struct dict_entry_func {
     49 	char		*key;
     50 	parse_item_f	func;
     51 };
     52 
     53 struct get_mdep_data {
     54 	struct hdp_application	*app;
     55 	gpointer		data;
     56 	hdp_continue_mdep_f	func;
     57 	GDestroyNotify		destroy;
     58 };
     59 
     60 struct conn_mcl_data {
     61 	int			refs;
     62 	gpointer		data;
     63 	hdp_continue_proc_f	func;
     64 	GDestroyNotify		destroy;
     65 	struct hdp_device	*dev;
     66 };
     67 
     68 struct get_dcpsm_data {
     69 	gpointer		data;
     70 	hdp_continue_dcpsm_f	func;
     71 	GDestroyNotify		destroy;
     72 };
     73 
     74 static gboolean parse_dict_entry(struct dict_entry_func dict_context[],
     75 							DBusMessageIter *iter,
     76 							GError **err,
     77 							gpointer user_data)
     78 {
     79 	DBusMessageIter entry;
     80 	char *key;
     81 	int ctype, i;
     82 	struct dict_entry_func df;
     83 
     84 	dbus_message_iter_recurse(iter, &entry);
     85 	ctype = dbus_message_iter_get_arg_type(&entry);
     86 	if (ctype != DBUS_TYPE_STRING) {
     87 		g_set_error(err, HDP_ERROR, HDP_DIC_ENTRY_PARSE_ERROR,
     88 			"Dictionary entries should have a string as key");
     89 		return FALSE;
     90 	}
     91 
     92 	dbus_message_iter_get_basic(&entry, &key);
     93 	dbus_message_iter_next(&entry);
     94 	/* Find function and call it */
     95 	for (i = 0, df = dict_context[0]; df.key; i++, df = dict_context[i]) {
     96 		if (g_ascii_strcasecmp(df.key, key) == 0)
     97 			return df.func(&entry, user_data, err);
     98 	}
     99 
    100 	g_set_error(err, HDP_ERROR, HDP_DIC_ENTRY_PARSE_ERROR,
    101 			"No function found for parsing value for key %s", key);
    102 	return FALSE;
    103 }
    104 
    105 static gboolean parse_dict(struct dict_entry_func dict_context[],
    106 							DBusMessageIter *iter,
    107 							GError **err,
    108 							gpointer user_data)
    109 {
    110 	int ctype;
    111 	DBusMessageIter dict;
    112 
    113 	ctype = dbus_message_iter_get_arg_type(iter);
    114 	if (ctype != DBUS_TYPE_ARRAY) {
    115 		g_set_error(err, HDP_ERROR, HDP_DIC_PARSE_ERROR,
    116 					"Dictionary should be an array");
    117 		return FALSE;
    118 	}
    119 
    120 	dbus_message_iter_recurse(iter, &dict);
    121 	while ((ctype = dbus_message_iter_get_arg_type(&dict)) !=
    122 							DBUS_TYPE_INVALID) {
    123 		if (ctype != DBUS_TYPE_DICT_ENTRY) {
    124 			g_set_error(err, HDP_ERROR, HDP_DIC_PARSE_ERROR,
    125 						"Dictionary array should "
    126 						"contain dict entries");
    127 			return FALSE;
    128 		}
    129 
    130 		/* Start parsing entry */
    131 		if (!parse_dict_entry(dict_context, &dict, err,
    132 							user_data))
    133 			return FALSE;
    134 		/* Finish entry parsing */
    135 
    136 		dbus_message_iter_next(&dict);
    137 	}
    138 
    139 	return TRUE;
    140 }
    141 
    142 static gboolean parse_data_type(DBusMessageIter *iter, gpointer data,
    143 								GError **err)
    144 {
    145 	struct hdp_application *app = data;
    146 	DBusMessageIter *value;
    147 	int ctype;
    148 
    149 	ctype = dbus_message_iter_get_arg_type(iter);
    150 	value = iter;
    151 	if (ctype == DBUS_TYPE_VARIANT) {
    152 		DBusMessageIter variant;
    153 
    154 		/* Get value inside the variable */
    155 		dbus_message_iter_recurse(iter, &variant);
    156 		ctype = dbus_message_iter_get_arg_type(&variant);
    157 		value = &variant;
    158 	}
    159 
    160 	if (ctype != DBUS_TYPE_UINT16) {
    161 		g_set_error(err, HDP_ERROR, HDP_DIC_ENTRY_PARSE_ERROR,
    162 			"Final value for data type should be uint16");
    163 		return FALSE;
    164 	}
    165 
    166 	dbus_message_iter_get_basic(value, &app->data_type);
    167 	app->data_type_set = TRUE;
    168 	return TRUE;
    169 }
    170 
    171 static gboolean parse_role(DBusMessageIter *iter, gpointer data, GError **err)
    172 {
    173 	struct hdp_application *app = data;
    174 	DBusMessageIter *string;
    175 	int ctype;
    176 	const char *role;
    177 
    178 	ctype = dbus_message_iter_get_arg_type(iter);
    179 	if (ctype == DBUS_TYPE_VARIANT) {
    180 		DBusMessageIter value;
    181 
    182 		/* Get value inside the variable */
    183 		dbus_message_iter_recurse(iter, &value);
    184 		ctype = dbus_message_iter_get_arg_type(&value);
    185 		string = &value;
    186 	} else {
    187 		string = iter;
    188 	}
    189 
    190 	if (ctype != DBUS_TYPE_STRING) {
    191 		g_set_error(err, HDP_ERROR, HDP_UNSPECIFIED_ERROR,
    192 				"Value data spec should be variable or string");
    193 		return FALSE;
    194 	}
    195 
    196 	dbus_message_iter_get_basic(string, &role);
    197 	if (g_ascii_strcasecmp(role, HDP_SINK_ROLE_AS_STRING) == 0) {
    198 		app->role = HDP_SINK;
    199 	} else if (g_ascii_strcasecmp(role, HDP_SOURCE_ROLE_AS_STRING) == 0) {
    200 		app->role = HDP_SOURCE;
    201 	} else {
    202 		g_set_error(err, HDP_ERROR, HDP_UNSPECIFIED_ERROR,
    203 			"Role value should be \"source\" or \"sink\"");
    204 		return FALSE;
    205 	}
    206 
    207 	app->role_set = TRUE;
    208 
    209 	return TRUE;
    210 }
    211 
    212 static gboolean parse_desc(DBusMessageIter *iter, gpointer data, GError **err)
    213 {
    214 	struct hdp_application *app = data;
    215 	DBusMessageIter *string;
    216 	int ctype;
    217 	const char *desc;
    218 
    219 	ctype = dbus_message_iter_get_arg_type(iter);
    220 	if (ctype == DBUS_TYPE_VARIANT) {
    221 		DBusMessageIter variant;
    222 
    223 		/* Get value inside the variable */
    224 		dbus_message_iter_recurse(iter, &variant);
    225 		ctype = dbus_message_iter_get_arg_type(&variant);
    226 		string = &variant;
    227 	} else {
    228 		string = iter;
    229 	}
    230 
    231 	if (ctype != DBUS_TYPE_STRING) {
    232 		g_set_error(err, HDP_ERROR, HDP_DIC_ENTRY_PARSE_ERROR,
    233 				"Value data spec should be variable or string");
    234 		return FALSE;
    235 	}
    236 
    237 	dbus_message_iter_get_basic(string, &desc);
    238 	app->description = g_strdup(desc);
    239 	return TRUE;
    240 }
    241 
    242 static gboolean parse_chan_type(DBusMessageIter *iter, gpointer data,
    243 								GError **err)
    244 {
    245 	struct hdp_application *app = data;
    246 	DBusMessageIter *value;
    247 	char *chan_type;
    248 	int ctype;
    249 
    250 	ctype = dbus_message_iter_get_arg_type(iter);
    251 	value = iter;
    252 	if (ctype == DBUS_TYPE_VARIANT) {
    253 		DBusMessageIter variant;
    254 
    255 		/* Get value inside the variable */
    256 		dbus_message_iter_recurse(iter, &variant);
    257 		ctype = dbus_message_iter_get_arg_type(&variant);
    258 		value = &variant;
    259 	}
    260 
    261 	if (ctype != DBUS_TYPE_STRING) {
    262 		g_set_error(err, HDP_ERROR, HDP_DIC_ENTRY_PARSE_ERROR,
    263 			"Final value for channel type should be an string");
    264 		return FALSE;
    265 	}
    266 
    267 	dbus_message_iter_get_basic(value, &chan_type);
    268 
    269 	if (g_ascii_strcasecmp("Reliable", chan_type) == 0)
    270 		app->chan_type = HDP_RELIABLE_DC;
    271 	else if (g_ascii_strcasecmp("Streaming", chan_type) == 0)
    272 		app->chan_type = HDP_STREAMING_DC;
    273 	else {
    274 		g_set_error(err, HDP_ERROR, HDP_DIC_ENTRY_PARSE_ERROR,
    275 						"Invalid value for data type");
    276 		return FALSE;
    277 	}
    278 
    279 	app->chan_type_set = TRUE;
    280 
    281 	return TRUE;
    282 }
    283 
    284 static struct dict_entry_func dict_parser[] = {
    285 	{"DataType",		parse_data_type},
    286 	{"Role",		parse_role},
    287 	{"Description",		parse_desc},
    288 	{"ChannelType",		parse_chan_type},
    289 	{NULL, NULL}
    290 };
    291 
    292 struct hdp_application *hdp_get_app_config(DBusMessageIter *iter, GError **err)
    293 {
    294 	struct hdp_application *app;
    295 
    296 	app = g_new0(struct hdp_application, 1);
    297 	app->ref = 1;
    298 	if (!parse_dict(dict_parser, iter, err, app))
    299 		goto fail;
    300 	if (!app->data_type_set || !app->role_set) {
    301 		g_set_error(err, HDP_ERROR, HDP_DIC_PARSE_ERROR,
    302 						"Mandatory fields aren't set");
    303 		goto fail;
    304 	}
    305 	return app;
    306 
    307 fail:
    308 	hdp_application_unref(app);
    309 	return NULL;
    310 }
    311 
    312 static gboolean is_app_role(GSList *app_list, HdpRole role)
    313 {
    314 	GSList *l;
    315 
    316 	for (l = app_list; l; l = l->next) {
    317 		struct hdp_application *app = l->data;
    318 
    319 		if (app->role == role)
    320 			return TRUE;
    321 	}
    322 
    323 	return FALSE;
    324 }
    325 
    326 static gboolean set_sdp_services_uuid(sdp_record_t *record, HdpRole role)
    327 {
    328 	uuid_t svc_uuid_source, svc_uuid_sink;
    329 	sdp_list_t *svc_list = NULL;
    330 
    331 	sdp_uuid16_create(&svc_uuid_sink, HDP_SINK_SVCLASS_ID);
    332 	sdp_uuid16_create(&svc_uuid_source, HDP_SOURCE_SVCLASS_ID);
    333 
    334 	sdp_get_service_classes(record, &svc_list);
    335 
    336 	if (role == HDP_SOURCE) {
    337 		if (!sdp_list_find(svc_list, &svc_uuid_source, sdp_uuid_cmp))
    338 			svc_list = sdp_list_append(svc_list, &svc_uuid_source);
    339 	} else if (role == HDP_SINK) {
    340 		if (!sdp_list_find(svc_list, &svc_uuid_sink, sdp_uuid_cmp))
    341 			svc_list = sdp_list_append(svc_list, &svc_uuid_sink);
    342 	}
    343 
    344 	if (sdp_set_service_classes(record, svc_list) < 0) {
    345 		sdp_list_free(svc_list, NULL);
    346 		return FALSE;
    347 	}
    348 
    349 	sdp_list_free(svc_list, NULL);
    350 
    351 	return TRUE;
    352 }
    353 
    354 static gboolean register_service_protocols(struct hdp_adapter *adapter,
    355 						sdp_record_t *sdp_record)
    356 {
    357 	gboolean ret;
    358 	uuid_t l2cap_uuid, mcap_c_uuid;
    359 	sdp_list_t *l2cap_list, *proto_list = NULL, *mcap_list = NULL;
    360 	sdp_list_t *access_proto_list = NULL;
    361 	sdp_data_t *psm = NULL, *mcap_ver = NULL;
    362 	uint16_t version = MCAP_VERSION;
    363 
    364 	/* set l2cap information */
    365 	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
    366 	l2cap_list = sdp_list_append(NULL, &l2cap_uuid);
    367 	if (!l2cap_list) {
    368 		ret = FALSE;
    369 		goto end;
    370 	}
    371 
    372 	psm = sdp_data_alloc(SDP_UINT16, &adapter->ccpsm);
    373 	if (!psm) {
    374 		ret = FALSE;
    375 		goto end;
    376 	}
    377 
    378 	if (!sdp_list_append(l2cap_list, psm)) {
    379 		ret = FALSE;
    380 		goto end;
    381 	}
    382 
    383 	proto_list = sdp_list_append(NULL, l2cap_list);
    384 	if (!proto_list) {
    385 		ret = FALSE;
    386 		goto end;
    387 	}
    388 
    389 	/* set mcap information */
    390 	sdp_uuid16_create(&mcap_c_uuid, MCAP_CTRL_UUID);
    391 	mcap_list = sdp_list_append(NULL, &mcap_c_uuid);
    392 	if (!mcap_list) {
    393 		ret = FALSE;
    394 		goto end;
    395 	}
    396 
    397 	mcap_ver = sdp_data_alloc(SDP_UINT16, &version);
    398 	if (!mcap_ver) {
    399 		ret = FALSE;
    400 		goto end;
    401 	}
    402 
    403 	if (!sdp_list_append(mcap_list, mcap_ver)) {
    404 		ret = FALSE;
    405 		goto end;
    406 	}
    407 
    408 	if (!sdp_list_append(proto_list, mcap_list)) {
    409 		ret = FALSE;
    410 		goto end;
    411 	}
    412 
    413 	/* attach protocol information to service record */
    414 	access_proto_list = sdp_list_append(NULL, proto_list);
    415 	if (!access_proto_list) {
    416 		ret = FALSE;
    417 		goto end;
    418 	}
    419 
    420 	if (sdp_set_access_protos(sdp_record, access_proto_list) < 0) {
    421 		ret = FALSE;
    422 		goto end;
    423 	}
    424 	ret = TRUE;
    425 
    426 end:
    427 	if (l2cap_list)
    428 		sdp_list_free(l2cap_list, NULL);
    429 	if (mcap_list)
    430 		sdp_list_free(mcap_list, NULL);
    431 	if (proto_list)
    432 		sdp_list_free(proto_list, NULL);
    433 	if (access_proto_list)
    434 		sdp_list_free(access_proto_list, NULL);
    435 	if (psm)
    436 		sdp_data_free(psm);
    437 	if (mcap_ver)
    438 		sdp_data_free(mcap_ver);
    439 
    440 	return ret;
    441 }
    442 
    443 static gboolean register_service_profiles(sdp_record_t *sdp_record)
    444 {
    445 	gboolean ret;
    446 	sdp_list_t *profile_list;
    447 	sdp_profile_desc_t hdp_profile;
    448 
    449 	/* set hdp information */
    450 	sdp_uuid16_create(&hdp_profile.uuid, HDP_SVCLASS_ID);
    451 	hdp_profile.version = HDP_VERSION;
    452 	profile_list = sdp_list_append(NULL, &hdp_profile);
    453 	if (!profile_list)
    454 		return FALSE;
    455 
    456 	/* set profile descriptor list */
    457 	if (sdp_set_profile_descs(sdp_record, profile_list) < 0)
    458 		ret = FALSE;
    459 	else
    460 		ret = TRUE;
    461 
    462 	sdp_list_free(profile_list, NULL);
    463 
    464 	return ret;
    465 }
    466 
    467 static gboolean register_service_additional_protocols(
    468 						struct hdp_adapter *adapter,
    469 						sdp_record_t *sdp_record)
    470 {
    471 	gboolean ret;
    472 	uuid_t l2cap_uuid, mcap_d_uuid;
    473 	sdp_list_t *l2cap_list, *proto_list = NULL, *mcap_list = NULL;
    474 	sdp_list_t *access_proto_list = NULL;
    475 	sdp_data_t *psm = NULL;
    476 
    477 	/* set l2cap information */
    478 	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
    479 	l2cap_list = sdp_list_append(NULL, &l2cap_uuid);
    480 	if (!l2cap_list) {
    481 		ret = FALSE;
    482 		goto end;
    483 	}
    484 
    485 	psm = sdp_data_alloc(SDP_UINT16, &adapter->dcpsm);
    486 	if (!psm) {
    487 		ret = FALSE;
    488 		goto end;
    489 	}
    490 
    491 	if (!sdp_list_append(l2cap_list, psm)) {
    492 		ret = FALSE;
    493 		goto end;
    494 	}
    495 
    496 	proto_list = sdp_list_append(NULL, l2cap_list);
    497 	if (!proto_list) {
    498 		ret = FALSE;
    499 		goto end;
    500 	}
    501 
    502 	/* set mcap information */
    503 	sdp_uuid16_create(&mcap_d_uuid, MCAP_DATA_UUID);
    504 	mcap_list = sdp_list_append(NULL, &mcap_d_uuid);
    505 	if (!mcap_list) {
    506 		ret = FALSE;
    507 		goto end;
    508 	}
    509 
    510 	if (!sdp_list_append(proto_list, mcap_list)) {
    511 		ret = FALSE;
    512 		goto end;
    513 	}
    514 
    515 	/* attach protocol information to service record */
    516 	access_proto_list = sdp_list_append(NULL, proto_list);
    517 	if (!access_proto_list) {
    518 		ret = FALSE;
    519 		goto end;
    520 	}
    521 
    522 	if (sdp_set_add_access_protos(sdp_record, access_proto_list) < 0)
    523 		ret = FALSE;
    524 	else
    525 		ret = TRUE;
    526 
    527 end:
    528 	if (l2cap_list)
    529 		sdp_list_free(l2cap_list, NULL);
    530 	if (mcap_list)
    531 		sdp_list_free(mcap_list, NULL);
    532 	if (proto_list)
    533 		sdp_list_free(proto_list, NULL);
    534 	if (access_proto_list)
    535 		sdp_list_free(access_proto_list, NULL);
    536 	if (psm)
    537 		sdp_data_free(psm);
    538 
    539 	return ret;
    540 }
    541 
    542 static sdp_list_t *app_to_sdplist(struct hdp_application *app)
    543 {
    544 	sdp_data_t *mdepid,
    545 		*dtype = NULL,
    546 		*role = NULL,
    547 		*desc = NULL;
    548 	sdp_list_t *f_list = NULL;
    549 
    550 	mdepid = sdp_data_alloc(SDP_UINT8, &app->id);
    551 	if (!mdepid)
    552 		return NULL;
    553 
    554 	dtype = sdp_data_alloc(SDP_UINT16, &app->data_type);
    555 	if (!dtype)
    556 		goto fail;
    557 
    558 	role = sdp_data_alloc(SDP_UINT8, &app->role);
    559 	if (!role)
    560 		goto fail;
    561 
    562 	if (app->description) {
    563 		desc = sdp_data_alloc(SDP_TEXT_STR8, app->description);
    564 		if (!desc)
    565 			goto fail;
    566 	}
    567 
    568 	f_list = sdp_list_append(NULL, mdepid);
    569 	if (!f_list)
    570 		goto fail;
    571 
    572 	if (!sdp_list_append(f_list, dtype))
    573 		goto fail;
    574 
    575 	if (!sdp_list_append(f_list, role))
    576 		goto fail;
    577 
    578 	if (desc)
    579 		if (!sdp_list_append(f_list, desc))
    580 			goto fail;
    581 
    582 	return f_list;
    583 
    584 fail:
    585 	if (f_list)
    586 		sdp_list_free(f_list, NULL);
    587 	if (mdepid)
    588 		sdp_data_free(mdepid);
    589 	if (dtype)
    590 		sdp_data_free(dtype);
    591 	if (role)
    592 		sdp_data_free(role);
    593 	if (desc)
    594 		sdp_data_free(desc);
    595 
    596 	return NULL;
    597 }
    598 
    599 static gboolean register_features(struct hdp_application *app,
    600 						sdp_list_t **sup_features)
    601 {
    602 	sdp_list_t *hdp_feature;
    603 
    604 	hdp_feature = app_to_sdplist(app);
    605 	if (!hdp_feature)
    606 		goto fail;
    607 
    608 	if (!*sup_features) {
    609 		*sup_features = sdp_list_append(NULL, hdp_feature);
    610 		if (!*sup_features)
    611 			goto fail;
    612 	} else if (!sdp_list_append(*sup_features, hdp_feature)) {
    613 		goto fail;
    614 	}
    615 
    616 	return TRUE;
    617 
    618 fail:
    619 	if (hdp_feature)
    620 		sdp_list_free(hdp_feature, (sdp_free_func_t)sdp_data_free);
    621 	return FALSE;
    622 }
    623 
    624 static void free_hdp_list(void *list)
    625 {
    626 	sdp_list_t *hdp_list = list;
    627 
    628 	sdp_list_free(hdp_list, (sdp_free_func_t)sdp_data_free);
    629 }
    630 
    631 static gboolean register_service_sup_features(GSList *app_list,
    632 						sdp_record_t *sdp_record)
    633 {
    634 	GSList *l;
    635 	sdp_list_t *sup_features = NULL;
    636 
    637 	for (l = app_list; l; l = l->next) {
    638 		if (!register_features(l->data, &sup_features))
    639 			return FALSE;
    640 	}
    641 
    642 	if (sdp_set_supp_feat(sdp_record, sup_features) < 0) {
    643 		sdp_list_free(sup_features, free_hdp_list);
    644 		return FALSE;
    645 	}
    646 
    647 	return TRUE;
    648 }
    649 
    650 static gboolean register_data_exchange_spec(sdp_record_t *record)
    651 {
    652 	sdp_data_t *spec;
    653 	uint8_t data_spec = DATA_EXCHANGE_SPEC_11073;
    654 	/* As by now 11073 is the only supported we set it by default */
    655 
    656 	spec = sdp_data_alloc(SDP_UINT8, &data_spec);
    657 	if (!spec)
    658 		return FALSE;
    659 
    660 	if (sdp_attr_add(record, SDP_ATTR_DATA_EXCHANGE_SPEC, spec) < 0) {
    661 		sdp_data_free(spec);
    662 		return FALSE;
    663 	}
    664 
    665 	return TRUE;
    666 }
    667 
    668 static gboolean register_mcap_features(sdp_record_t *sdp_record)
    669 {
    670 	sdp_data_t *mcap_proc;
    671 	uint8_t mcap_sup_proc = MCAP_SUP_PROC;
    672 
    673 	mcap_proc = sdp_data_alloc(SDP_UINT8, &mcap_sup_proc);
    674 	if (!mcap_proc)
    675 		return FALSE;
    676 
    677 	if (sdp_attr_add(sdp_record, SDP_ATTR_MCAP_SUPPORTED_PROCEDURES,
    678 							mcap_proc) < 0) {
    679 		sdp_data_free(mcap_proc);
    680 		return FALSE;
    681 	}
    682 
    683 	return TRUE;
    684 }
    685 
    686 gboolean hdp_update_sdp_record(struct hdp_adapter *adapter, GSList *app_list)
    687 {
    688 	sdp_record_t *sdp_record;
    689 	bdaddr_t addr;
    690 
    691 	if (adapter->sdp_handler)
    692 		remove_record_from_server(adapter->sdp_handler);
    693 
    694 	if (!app_list) {
    695 		adapter->sdp_handler = 0;
    696 		return TRUE;
    697 	}
    698 
    699 	sdp_record = sdp_record_alloc();
    700 	if (!sdp_record)
    701 		return FALSE;
    702 
    703 	if (adapter->sdp_handler)
    704 		sdp_record->handle = adapter->sdp_handler;
    705 	else
    706 		sdp_record->handle = 0xffffffff; /* Set automatically */
    707 
    708 	if (is_app_role(app_list, HDP_SINK))
    709 		set_sdp_services_uuid(sdp_record, HDP_SINK);
    710 	if (is_app_role(app_list, HDP_SOURCE))
    711 		set_sdp_services_uuid(sdp_record, HDP_SOURCE);
    712 
    713 	if (!register_service_protocols(adapter, sdp_record))
    714 		goto fail;
    715 	if (!register_service_profiles(sdp_record))
    716 		goto fail;
    717 	if (!register_service_additional_protocols(adapter, sdp_record))
    718 		goto fail;
    719 
    720 	sdp_set_info_attr(sdp_record, HDP_SERVICE_NAME, HDP_SERVICE_PROVIDER,
    721 							HDP_SERVICE_DSC);
    722 	if (!register_service_sup_features(app_list, sdp_record))
    723 		goto fail;
    724 	if (!register_data_exchange_spec(sdp_record))
    725 		goto fail;
    726 
    727 	register_mcap_features(sdp_record);
    728 
    729 	if (sdp_set_record_state(sdp_record, adapter->record_state++))
    730 		goto fail;
    731 
    732 	adapter_get_address(adapter->btd_adapter, &addr);
    733 
    734 	if (add_record_to_server(&addr, sdp_record) < 0)
    735 		goto fail;
    736 	adapter->sdp_handler = sdp_record->handle;
    737 	return TRUE;
    738 
    739 fail:
    740 	if (sdp_record)
    741 		sdp_record_free(sdp_record);
    742 	return FALSE;
    743 }
    744 
    745 static gboolean check_role(uint8_t rec_role, uint8_t app_role)
    746 {
    747 	if ((rec_role == HDP_SINK && app_role == HDP_SOURCE) ||
    748 			(rec_role == HDP_SOURCE && app_role == HDP_SINK))
    749 		return TRUE;
    750 
    751 	return FALSE;
    752 }
    753 
    754 static gboolean get_mdep_from_rec(const sdp_record_t *rec, uint8_t role,
    755 				uint16_t d_type, uint8_t *mdep, char **desc)
    756 {
    757 	sdp_data_t *list, *feat;
    758 
    759 	if (!desc && !mdep)
    760 		return TRUE;
    761 
    762 	list = sdp_data_get(rec, SDP_ATTR_SUPPORTED_FEATURES_LIST);
    763 
    764 	if (list->dtd != SDP_SEQ8 && list->dtd != SDP_SEQ16 &&
    765 							list->dtd != SDP_SEQ32)
    766 		return FALSE;
    767 
    768 	for (feat = list->val.dataseq; feat; feat = feat->next) {
    769 		sdp_data_t *data_type, *mdepid, *role_t, *desc_t;
    770 
    771 		if (feat->dtd != SDP_SEQ8 && feat->dtd != SDP_SEQ16 &&
    772 						feat->dtd != SDP_SEQ32)
    773 			continue;
    774 
    775 		mdepid = feat->val.dataseq;
    776 		if (!mdepid)
    777 			continue;
    778 
    779 		data_type = mdepid->next;
    780 		if (!data_type)
    781 			continue;
    782 
    783 		role_t = data_type->next;
    784 		if (!role_t)
    785 			continue;
    786 
    787 		desc_t = role_t->next;
    788 
    789 		if (data_type->dtd != SDP_UINT16 || mdepid->dtd != SDP_UINT8 ||
    790 						role_t->dtd != SDP_UINT8)
    791 			continue;
    792 
    793 		if (data_type->val.uint16 != d_type ||
    794 					!check_role(role_t->val.uint8, role))
    795 			continue;
    796 
    797 		if (mdep)
    798 			*mdep = mdepid->val.uint8;
    799 
    800 		if (desc  && desc_t && (desc_t->dtd == SDP_TEXT_STR8 ||
    801 					desc_t->dtd == SDP_TEXT_STR16  ||
    802 					desc_t->dtd == SDP_TEXT_STR32))
    803 			*desc = g_strdup(desc_t->val.str);
    804 
    805 		return TRUE;
    806 	}
    807 
    808 	return FALSE;
    809 }
    810 
    811 static void get_mdep_cb(sdp_list_t *recs, int err, gpointer user_data)
    812 {
    813 	struct get_mdep_data *mdep_data = user_data;
    814 	GError *gerr = NULL;
    815 	uint8_t mdep;
    816 
    817 	if (err || !recs) {
    818 		g_set_error(&gerr, HDP_ERROR, HDP_CONNECTION_ERROR,
    819 					"Error getting remote SDP records");
    820 		mdep_data->func(0, mdep_data->data, gerr);
    821 		g_error_free(gerr);
    822 		return;
    823 	}
    824 
    825 	if (!get_mdep_from_rec(recs->data, mdep_data->app->role,
    826 				mdep_data->app->data_type, &mdep, NULL)) {
    827 		g_set_error(&gerr, HDP_ERROR, HDP_CONNECTION_ERROR,
    828 					"No matching MDEP found");
    829 		mdep_data->func(0, mdep_data->data, gerr);
    830 		g_error_free(gerr);
    831 		return;
    832 	}
    833 
    834 	mdep_data->func(mdep, mdep_data->data, NULL);
    835 }
    836 
    837 static void free_mdep_data(gpointer data)
    838 {
    839 	struct get_mdep_data *mdep_data = data;
    840 
    841 	if (mdep_data->destroy)
    842 		mdep_data->destroy(mdep_data->data);
    843 	hdp_application_unref(mdep_data->app);
    844 
    845 	g_free(mdep_data);
    846 }
    847 
    848 gboolean hdp_get_mdep(struct hdp_device *device, struct hdp_application *app,
    849 				hdp_continue_mdep_f func, gpointer data,
    850 				GDestroyNotify destroy, GError **err)
    851 {
    852 	struct get_mdep_data *mdep_data;
    853 	bdaddr_t dst, src;
    854 	uuid_t uuid;
    855 
    856 	device_get_address(device->dev, &dst);
    857 	adapter_get_address(device_get_adapter(device->dev), &src);
    858 
    859 	mdep_data = g_new0(struct get_mdep_data, 1);
    860 	mdep_data->app = hdp_application_ref(app);
    861 	mdep_data->func = func;
    862 	mdep_data->data = data;
    863 	mdep_data->destroy = destroy;
    864 
    865 	bt_string2uuid(&uuid, HDP_UUID);
    866 	if (bt_search_service(&src, &dst, &uuid, get_mdep_cb, mdep_data,
    867 							free_mdep_data)) {
    868 		g_set_error(err, HDP_ERROR, HDP_CONNECTION_ERROR,
    869 						"Can't get remote SDP record");
    870 		g_free(mdep_data);
    871 		return FALSE;
    872 	}
    873 
    874 	return TRUE;
    875 }
    876 
    877 static gboolean get_prot_desc_entry(sdp_data_t *entry, int type, guint16 *val)
    878 {
    879 	sdp_data_t *iter;
    880 	int proto;
    881 
    882 	if (!entry || (entry->dtd != SDP_SEQ8 && entry->dtd != SDP_SEQ16 &&
    883 						entry->dtd != SDP_SEQ32))
    884 		return FALSE;
    885 
    886 	iter = entry->val.dataseq;
    887 	if (!(iter->dtd & SDP_UUID_UNSPEC))
    888 		return FALSE;
    889 
    890 	proto = sdp_uuid_to_proto(&iter->val.uuid);
    891 	if (proto != type)
    892 		return FALSE;
    893 
    894 	if (!val)
    895 		return TRUE;
    896 
    897 	iter = iter->next;
    898 	if (iter->dtd != SDP_UINT16)
    899 		return FALSE;
    900 
    901 	*val = iter->val.uint16;
    902 
    903 	return TRUE;
    904 }
    905 
    906 static gboolean hdp_get_prot_desc_list(const sdp_record_t *rec, guint16 *psm,
    907 							guint16 *version)
    908 {
    909 	sdp_data_t *pdl, *p0, *p1;
    910 
    911 	if (!psm && !version)
    912 		return TRUE;
    913 
    914 	pdl = sdp_data_get(rec, SDP_ATTR_PROTO_DESC_LIST);
    915 	if (pdl->dtd != SDP_SEQ8 && pdl->dtd != SDP_SEQ16 &&
    916 							pdl->dtd != SDP_SEQ32)
    917 		return FALSE;
    918 
    919 	p0 = pdl->val.dataseq;
    920 	if (!get_prot_desc_entry(p0, L2CAP_UUID, psm))
    921 		return FALSE;
    922 
    923 	p1 = p0->next;
    924 	if (!get_prot_desc_entry(p1, MCAP_CTRL_UUID, version))
    925 		return FALSE;
    926 
    927 	return TRUE;
    928 }
    929 
    930 static gboolean hdp_get_add_prot_desc_list(const sdp_record_t *rec,
    931 								guint16 *psm)
    932 {
    933 	sdp_data_t *pdl, *p0, *p1;
    934 
    935 	if (!psm)
    936 		return TRUE;
    937 
    938 	pdl = sdp_data_get(rec, SDP_ATTR_ADD_PROTO_DESC_LIST);
    939 	if (pdl->dtd != SDP_SEQ8)
    940 		return FALSE;
    941 	pdl = pdl->val.dataseq;
    942 	if (pdl->dtd != SDP_SEQ8)
    943 		return FALSE;
    944 
    945 	p0 = pdl->val.dataseq;
    946 
    947 	if (!get_prot_desc_entry(p0, L2CAP_UUID, psm))
    948 		return FALSE;
    949 	p1 = p0->next;
    950 	if (!get_prot_desc_entry(p1, MCAP_DATA_UUID, NULL))
    951 		return FALSE;
    952 
    953 	return TRUE;
    954 }
    955 
    956 static gboolean get_ccpsm(sdp_list_t *recs, uint16_t *ccpsm)
    957 {
    958 	sdp_list_t *l;
    959 
    960 	for (l = recs; l; l = l->next) {
    961 		sdp_record_t *rec = l->data;
    962 
    963 		if (hdp_get_prot_desc_list(rec, ccpsm, NULL))
    964 			return TRUE;
    965 	}
    966 
    967 	return FALSE;
    968 }
    969 
    970 static gboolean get_dcpsm(sdp_list_t *recs, uint16_t *dcpsm)
    971 {
    972 	sdp_list_t *l;
    973 
    974 	for (l = recs; l; l = l->next) {
    975 		sdp_record_t *rec = l->data;
    976 
    977 		if (hdp_get_add_prot_desc_list(rec, dcpsm))
    978 			return TRUE;
    979 	}
    980 
    981 	return FALSE;
    982 }
    983 
    984 static void con_mcl_data_unref(struct conn_mcl_data *conn_data)
    985 {
    986 	if (!conn_data)
    987 		return;
    988 
    989 	if (--conn_data->refs > 0)
    990 		return;
    991 
    992 	if (conn_data->destroy)
    993 		conn_data->destroy(conn_data->data);
    994 
    995 	health_device_unref(conn_data->dev);
    996 	g_free(conn_data);
    997 }
    998 
    999 static void destroy_con_mcl_data(gpointer data)
   1000 {
   1001 	con_mcl_data_unref(data);
   1002 }
   1003 
   1004 static struct conn_mcl_data *con_mcl_data_ref(struct conn_mcl_data *conn_data)
   1005 {
   1006 	if (!conn_data)
   1007 		return NULL;
   1008 
   1009 	conn_data->refs++;
   1010 	return conn_data;
   1011 }
   1012 
   1013 static void create_mcl_cb(struct mcap_mcl *mcl, GError *err, gpointer data)
   1014 {
   1015 	struct conn_mcl_data *conn_data = data;
   1016 	struct hdp_device *device = conn_data->dev;
   1017 	GError *gerr = NULL;
   1018 
   1019 	if (err) {
   1020 		conn_data->func(conn_data->data, err);
   1021 		return;
   1022 	}
   1023 
   1024 	if (!device->mcl)
   1025 		device->mcl = mcap_mcl_ref(mcl);
   1026 	device->mcl_conn = TRUE;
   1027 
   1028 	hdp_set_mcl_cb(device, &gerr);
   1029 
   1030 	conn_data->func(conn_data->data, gerr);
   1031 	if (gerr)
   1032 		g_error_free(gerr);
   1033 }
   1034 
   1035 static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
   1036 {
   1037 	struct conn_mcl_data *conn_data = user_data;
   1038 	GError *gerr = NULL;
   1039 	bdaddr_t dst;
   1040 	uint16_t ccpsm;
   1041 
   1042 	if (!conn_data->dev->hdp_adapter->mi) {
   1043 		g_set_error(&gerr, HDP_ERROR, HDP_CONNECTION_ERROR,
   1044 						"Mcap instance released");
   1045 		goto fail;
   1046 	}
   1047 
   1048 	if (err || !recs) {
   1049 		g_set_error(&gerr, HDP_ERROR, HDP_CONNECTION_ERROR,
   1050 					"Error getting remote SDP records");
   1051 		goto fail;
   1052 	}
   1053 
   1054 	if (!get_ccpsm(recs, &ccpsm)) {
   1055 		g_set_error(&gerr, HDP_ERROR, HDP_CONNECTION_ERROR,
   1056 				"Can't get remote PSM for control channel");
   1057 		goto fail;
   1058 	}
   1059 
   1060 	conn_data = con_mcl_data_ref(conn_data);
   1061 
   1062 	device_get_address(conn_data->dev->dev, &dst);
   1063 	if (!mcap_create_mcl(conn_data->dev->hdp_adapter->mi, &dst, ccpsm,
   1064 						create_mcl_cb, conn_data,
   1065 						destroy_con_mcl_data, &gerr)) {
   1066 		con_mcl_data_unref(conn_data);
   1067 		goto fail;
   1068 	}
   1069 	return;
   1070 fail:
   1071 	conn_data->func(conn_data->data, gerr);
   1072 	g_error_free(gerr);
   1073 }
   1074 
   1075 gboolean hdp_establish_mcl(struct hdp_device *device,
   1076 						hdp_continue_proc_f func,
   1077 						gpointer data,
   1078 						GDestroyNotify destroy,
   1079 						GError **err)
   1080 {
   1081 	struct conn_mcl_data *conn_data;
   1082 	bdaddr_t dst, src;
   1083 	uuid_t uuid;
   1084 
   1085 	device_get_address(device->dev, &dst);
   1086 	adapter_get_address(device_get_adapter(device->dev), &src);
   1087 
   1088 	conn_data = g_new0(struct conn_mcl_data, 1);
   1089 	conn_data->refs = 1;
   1090 	conn_data->func = func;
   1091 	conn_data->data = data;
   1092 	conn_data->destroy = destroy;
   1093 	conn_data->dev = health_device_ref(device);
   1094 
   1095 	bt_string2uuid(&uuid, HDP_UUID);
   1096 	if (bt_search_service(&src, &dst, &uuid, search_cb, conn_data,
   1097 						destroy_con_mcl_data)) {
   1098 		g_set_error(err, HDP_ERROR, HDP_CONNECTION_ERROR,
   1099 						"Can't get remote SDP record");
   1100 		g_free(conn_data);
   1101 		return FALSE;
   1102 	}
   1103 
   1104 	return TRUE;
   1105 }
   1106 
   1107 static void get_dcpsm_cb(sdp_list_t *recs, int err, gpointer data)
   1108 {
   1109 	struct get_dcpsm_data *dcpsm_data = data;
   1110 	GError *gerr = NULL;
   1111 	uint16_t dcpsm;
   1112 
   1113 	if (err || !recs) {
   1114 		g_set_error(&gerr, HDP_ERROR, HDP_CONNECTION_ERROR,
   1115 					"Error getting remote SDP records");
   1116 		goto fail;
   1117 	}
   1118 
   1119 	if (!get_dcpsm(recs, &dcpsm)) {
   1120 		g_set_error(&gerr, HDP_ERROR, HDP_CONNECTION_ERROR,
   1121 				"Can't get remote PSM for data channel");
   1122 		goto fail;
   1123 	}
   1124 
   1125 	dcpsm_data->func(dcpsm, dcpsm_data->data, NULL);
   1126 	return;
   1127 
   1128 fail:
   1129 	dcpsm_data->func(0, dcpsm_data->data, gerr);
   1130 	g_error_free(gerr);
   1131 }
   1132 
   1133 static void free_dcpsm_data(gpointer data)
   1134 {
   1135 	struct get_dcpsm_data *dcpsm_data = data;
   1136 
   1137 	if (!dcpsm_data)
   1138 		return;
   1139 
   1140 	if (dcpsm_data->destroy)
   1141 		dcpsm_data->destroy(dcpsm_data->data);
   1142 
   1143 	g_free(dcpsm_data);
   1144 }
   1145 
   1146 gboolean hdp_get_dcpsm(struct hdp_device *device, hdp_continue_dcpsm_f func,
   1147 							gpointer data,
   1148 							GDestroyNotify destroy,
   1149 							GError **err)
   1150 {
   1151 	struct get_dcpsm_data *dcpsm_data;
   1152 	bdaddr_t dst, src;
   1153 	uuid_t uuid;
   1154 
   1155 	device_get_address(device->dev, &dst);
   1156 	adapter_get_address(device_get_adapter(device->dev), &src);
   1157 
   1158 	dcpsm_data = g_new0(struct get_dcpsm_data, 1);
   1159 	dcpsm_data->func = func;
   1160 	dcpsm_data->data = data;
   1161 	dcpsm_data->destroy = destroy;
   1162 
   1163 	bt_string2uuid(&uuid, HDP_UUID);
   1164 	if (bt_search_service(&src, &dst, &uuid, get_dcpsm_cb, dcpsm_data,
   1165 							free_dcpsm_data)) {
   1166 		g_set_error(err, HDP_ERROR, HDP_CONNECTION_ERROR,
   1167 						"Can't get remote SDP record");
   1168 		g_free(dcpsm_data);
   1169 		return FALSE;
   1170 	}
   1171 
   1172 	return TRUE;
   1173 }
   1174 
   1175 static void hdp_free_application(struct hdp_application *app)
   1176 {
   1177 	if (app->dbus_watcher)
   1178 		g_dbus_remove_watch(app->conn, app->dbus_watcher);
   1179 
   1180 	if (app->conn)
   1181 		dbus_connection_unref(app->conn);
   1182 	g_free(app->oname);
   1183 	g_free(app->description);
   1184 	g_free(app->path);
   1185 	g_free(app);
   1186 }
   1187 
   1188 struct hdp_application *hdp_application_ref(struct hdp_application *app)
   1189 {
   1190 	if (!app)
   1191 		return NULL;
   1192 
   1193 	app->ref++;
   1194 
   1195 	DBG("health_application_ref(%p): ref=%d", app, app->ref);
   1196 	return app;
   1197 }
   1198 
   1199 void hdp_application_unref(struct hdp_application *app)
   1200 {
   1201 	if (!app)
   1202 		return;
   1203 
   1204 	app->ref --;
   1205 
   1206 	DBG("health_application_unref(%p): ref=%d", app, app->ref);
   1207 	if (app->ref > 0)
   1208 		return;
   1209 
   1210 	hdp_free_application(app);
   1211 }
   1212