static DBusMessage *add_sap_service_record(DBusConnection *conn, DBusMessage *msg,
                        void *data)
{
   DBG("");

   sdp_record_t *record = NULL;
   GError *gerr = NULL;

	record = create_sap_record(SAP_SERVER_CHANNEL);
	if (!record) {
		error("Creating SAP SDP record failed.");
		goto sdp_err;
	}

	if (add_record_to_server(&server->src, record) < 0) {
		error("Adding SAP SDP record to the SDP server failed.");
		sdp_record_free(record);
		goto sdp_err;
	}

	server->record_id = record->handle;

   DBG("EXIT");

   return dbus_message_new_method_return(msg);

sdp_err:
	server_free(server);
	sap_exit();
   return dbus_message_new_method_return(msg);
}
Example #2
0
static DBusMessage *update_record(DBusConnection *conn, DBusMessage *msg,
		struct service_adapter *serv_adapter,
		dbus_uint32_t handle, sdp_record_t *sdp_record)
{
	bdaddr_t src;
	int err;

	if (remove_record_from_server(handle) < 0) {
		sdp_record_free(sdp_record);
		return btd_error_not_available(msg);
	}

	if (serv_adapter->adapter)
		adapter_get_address(serv_adapter->adapter, &src);
	else
		bacpy(&src, BDADDR_ANY);

	sdp_record->handle = handle;
	err = add_record_to_server(&src, sdp_record);
	if (err < 0) {
		sdp_record_free(sdp_record);
		error("Failed to update the service record");
		return btd_error_failed(msg, strerror(-err));
	}

	return dbus_message_new_method_return(msg);
}
Example #3
0
static struct a2dp_sep *a2dp_add_sep(DBusConnection *conn, uint8_t type,
					uint8_t codec)
{
	struct a2dp_sep *sep;
	GSList **l;
	sdp_record_t *(*create_record)(void);
	uint32_t *record_id;
	sdp_record_t *record;
	struct avdtp_sep_ind *ind;

	sep = g_new0(struct a2dp_sep, 1);

	ind = (codec == A2DP_CODEC_MPEG12) ? &mpeg_ind : &sbc_ind;
	sep->sep = avdtp_register_sep(type, AVDTP_MEDIA_TYPE_AUDIO, codec,
					ind, &cfm, sep);
	if (sep->sep == NULL) {
		g_free(sep);
		return NULL;
	}

	sep->codec = codec;
	sep->type = type;

	if (type == AVDTP_SEP_TYPE_SOURCE) {
		l = &sources;
		create_record = a2dp_source_record;
		record_id = &source_record_id;
	} else {
		l = &sinks;
		create_record = a2dp_sink_record;
		record_id = &sink_record_id;
	}

	if (*record_id != 0)
		goto add;

	record = create_record();
	if (!record) {
		error("Unable to allocate new service record");
		avdtp_unregister_sep(sep->sep);
		g_free(sep);
		return NULL;
	}

	if (add_record_to_server(BDADDR_ANY, record) < 0) {
		error("Unable to register A2DP service record");\
		sdp_record_free(record);
		avdtp_unregister_sep(sep->sep);
		g_free(sep);
		return NULL;
	}
	*record_id = record->handle;

add:
	*l = g_slist_append(*l, sep);

	return sep;
}
Example #4
0
static struct a2dp_sep *a2dp_add_sep(struct a2dp_server *server, uint8_t type,
                                     uint8_t codec, gboolean delay_reporting)
{
    struct a2dp_sep *sep;
    GSList **l;
    uint32_t *record_id;
    sdp_record_t *record;
    struct avdtp_sep_ind *ind;

    sep = g_new0(struct a2dp_sep, 1);

    ind = (codec == A2DP_CODEC_MPEG12) ? &mpeg_ind : &sbc_ind;
    sep->sep = avdtp_register_sep(&server->src, type,
                                  AVDTP_MEDIA_TYPE_AUDIO, codec,
                                  delay_reporting, ind, &cfm, sep);
    if (sep->sep == NULL) {
        g_free(sep);
        return NULL;
    }

    sep->codec = codec;
    sep->type = type;
    sep->delay_reporting = delay_reporting;

    if (type == AVDTP_SEP_TYPE_SOURCE) {
        l = &server->sources;
        record_id = &server->source_record_id;
    } else {
        l = &server->sinks;
        record_id = &server->sink_record_id;
    }

    if (*record_id != 0)
        goto add;

    record = a2dp_record(type, server->version);
    if (!record) {
        error("Unable to allocate new service record");
        avdtp_unregister_sep(sep->sep);
        g_free(sep);
        return NULL;
    }

    if (add_record_to_server(&server->src, record) < 0) {
        error("Unable to register A2DP service record");
        \
        sdp_record_free(record);
        avdtp_unregister_sep(sep->sep);
        g_free(sep);
        return NULL;
    }
    *record_id = record->handle;

add:
    *l = g_slist_append(*l, sep);

    return sep;
}
gboolean hdp_update_sdp_record(struct hdp_adapter *adapter, GSList *app_list)
{
	sdp_record_t *sdp_record;
	bdaddr_t addr;

	if (adapter->sdp_handler)
		remove_record_from_server(adapter->sdp_handler);

	if (!app_list) {
		adapter->sdp_handler = 0;
		return TRUE;
	}

	sdp_record = sdp_record_alloc();
	if (!sdp_record)
		return FALSE;

	if (adapter->sdp_handler)
		sdp_record->handle = adapter->sdp_handler;
	else
		sdp_record->handle = 0xffffffff; /* Set automatically */

	if (is_app_role(app_list, HDP_SINK))
		set_sdp_services_uuid(sdp_record, HDP_SINK);
	if (is_app_role(app_list, HDP_SOURCE))
		set_sdp_services_uuid(sdp_record, HDP_SOURCE);

	if (!register_service_protocols(adapter, sdp_record))
		goto fail;
	if (!register_service_profiles(sdp_record))
		goto fail;
	if (!register_service_additional_protocols(adapter, sdp_record))
		goto fail;

	sdp_set_info_attr(sdp_record, HDP_SERVICE_NAME, HDP_SERVICE_PROVIDER,
							HDP_SERVICE_DSC);
	if (!register_service_sup_features(app_list, sdp_record))
		goto fail;
	if (!register_data_exchange_spec(sdp_record))
		goto fail;

	register_mcap_features(sdp_record);

	if (sdp_set_record_state(sdp_record, adapter->record_state++))
		goto fail;

	adapter_get_address(adapter->btd_adapter, &addr);

	if (add_record_to_server(&addr, sdp_record) < 0)
		goto fail;
	adapter->sdp_handler = sdp_record->handle;
	return TRUE;

fail:
	if (sdp_record)
		sdp_record_free(sdp_record);
	return FALSE;
}
Example #6
0
File: pnat.c Project: 520lly/bluez
static int pnat_probe(struct btd_adapter *adapter)
{
	struct dun_server *server;
	GIOChannel *io;
	GError *err = NULL;
	sdp_record_t *record;
	bdaddr_t src;

	adapter_get_address(adapter, &src);

	server = g_new0(struct dun_server, 1);

	io = bt_io_listen(BT_IO_RFCOMM, NULL, confirm_cb, server, NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, &src,
				BT_IO_OPT_CHANNEL, DUN_CHANNEL,
				BT_IO_OPT_INVALID);
	if (err != NULL) {
		error("Failed to start DUN server: %s", err->message);
		g_error_free(err);
		goto fail;
	}

	record = dun_record(DUN_CHANNEL);
	if (!record) {
		error("Unable to allocate new service record");
		goto fail;
	}

	if (add_record_to_server(&src, record) < 0) {
		error("Unable to register DUN service record");
		goto fail;
	}

	server->rfcomm_ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_RFCOMM);
	if (server->rfcomm_ctl < 0) {
		error("Unable to create RFCOMM control socket: %s (%d)",
						strerror(errno), errno);
		goto fail;
	}

	server->server = io;
	server->record_handle = record->handle;
	bacpy(&server->bda, &src);

	servers = g_slist_append(servers, server);

	return 0;

fail:
	if (io != NULL)
		g_io_channel_unref(io);
	g_free(server);
	return -EIO;
}
Example #7
0
static int gateway_server_init(struct audio_adapter *adapter)
{
	uint8_t chan = DEFAULT_HFP_HS_CHANNEL;
	sdp_record_t *record;
	gboolean master = TRUE;
	GError *err = NULL;
	GIOChannel *io;
	bdaddr_t src;

	if (config) {
		gboolean tmp;

		tmp = g_key_file_get_boolean(config, "General", "Master",
						&err);
		if (err) {
			DBG("audio.conf: %s", err->message);
			g_clear_error(&err);
		} else
			master = tmp;
	}

	adapter_get_address(adapter->btd_adapter, &src);

	io = bt_io_listen(BT_IO_RFCOMM, NULL, hf_io_cb, adapter, NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, &src,
				BT_IO_OPT_CHANNEL, chan,
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
				BT_IO_OPT_MASTER, master,
				BT_IO_OPT_INVALID);
	if (!io) {
		error("%s", err->message);
		g_error_free(err);
		return -1;
	}

	adapter->hfp_hs_server = io;
	record = hfp_hs_record(chan);
	if (!record) {
		error("Unable to allocate new service record");
		return -1;
	}

	if (add_record_to_server(&src, record) < 0) {
		error("Unable to register HFP HS service record");
		sdp_record_free(record);
		g_io_channel_unref(adapter->hfp_hs_server);
		adapter->hfp_hs_server = NULL;
		return -1;
	}

	adapter->hfp_hs_record_id = record->handle;

	return 0;
}
Example #8
0
static DBusMessage *proxy_enable(DBusConnection *conn,
                                 DBusMessage *msg, void *data)
{
    struct serial_proxy *prx = data;
    sdp_record_t *record;
    GError *err = NULL;
    DBusMessage *reply;

    if (prx->io)
        return failed(msg, "Already enabled");

    /* Listen */
    prx->io = bt_io_listen(BT_IO_RFCOMM, NULL, confirm_event_cb, prx,
                           NULL, &err,
                           BT_IO_OPT_SOURCE_BDADDR, &prx->src,
                           BT_IO_OPT_INVALID);
    if (!prx->io)
        goto failed;

    bt_io_get(prx->io, BT_IO_RFCOMM, &err,
              BT_IO_OPT_CHANNEL, &prx->channel,
              BT_IO_OPT_INVALID);
    if (err) {
        g_io_channel_unref(prx->io);
        prx->io = NULL;
        goto failed;
    }

    debug("Allocated channel %d", prx->channel);

    g_io_channel_set_close_on_unref(prx->io, TRUE);

    record = proxy_record_new(prx->uuid128, prx->channel);
    if (!record) {
        g_io_channel_unref(prx->io);
        return failed(msg, "Unable to allocate new service record");
    }

    if (add_record_to_server(&prx->src, record) < 0) {
        sdp_record_free(record);
        g_io_channel_unref(prx->io);
        return failed(msg, "Service registration failed");
    }

    prx->record_id = record->handle;

    return dbus_message_new_method_return(msg);

failed:
    error("%s", err->message);
    reply = failed(msg, err->message);
    g_error_free(err);
    return reply;
}
Example #9
0
static int enable_proxy(struct serial_proxy *prx)
{
	sdp_record_t *record;
	GError *gerr = NULL;
	int err;

	if (prx->io)
		return -EALREADY;

	/* Listen */
	prx->io = bt_io_listen(BT_IO_RFCOMM, NULL, confirm_event_cb, prx,
				NULL, &gerr,
				BT_IO_OPT_SOURCE_BDADDR, &prx->src,
				BT_IO_OPT_INVALID);
	if (!prx->io)
		goto failed;

	bt_io_get(prx->io, BT_IO_RFCOMM, &gerr,
			BT_IO_OPT_CHANNEL, &prx->channel,
			BT_IO_OPT_INVALID);
	if (gerr) {
		g_io_channel_unref(prx->io);
		prx->io = NULL;
		goto failed;
	}

	debug("Allocated channel %d", prx->channel);

	g_io_channel_set_close_on_unref(prx->io, TRUE);

	record = proxy_record_new(prx->uuid128, prx->channel);
	if (!record) {
		g_io_channel_unref(prx->io);
		return -ENOMEM;
	}

	err = add_record_to_server(&prx->src, record);
	if (err < 0) {
		sdp_record_free(record);
		g_io_channel_unref(prx->io);
		return err;
	}

	prx->record_id = record->handle;

	return 0;

failed:
	error("%s", gerr->message);
	g_error_free(gerr);
	return -EIO;

}
Example #10
0
static uint32_t register_server_record(struct network_server *ns)
{
	sdp_record_t *record;

	record = server_record_new(ns->name, ns->id);
	if (!record) {
		error("Unable to allocate new service record");
		return 0;
	}

	if (add_record_to_server(&ns->src, record) < 0) {
		error("Failed to register service record");
		sdp_record_free(record);
		return 0;
	}

	DBG("got record id 0x%x", record->handle);

	return record->handle;
}
Example #11
0
static int add_xml_record(DBusConnection *conn, const char *sender,
			struct service_adapter *serv_adapter,
			const char *record, dbus_uint32_t *handle)
{
	struct record_data *user_record;
	sdp_record_t *sdp_record;
	bdaddr_t src;

	sdp_record = sdp_xml_parse_record(record, strlen(record));
	if (!sdp_record) {
		error("Parsing of XML service record failed");
		return -EIO;
	}

	if (serv_adapter->adapter)
		adapter_get_address(serv_adapter->adapter, &src);
	else
		bacpy(&src, BDADDR_ANY);

	if (add_record_to_server(&src, sdp_record) < 0) {
		error("Failed to register service record");
		sdp_record_free(sdp_record);
		return -EIO;
	}

	user_record = g_new0(struct record_data, 1);
	user_record->handle = sdp_record->handle;
	user_record->sender = g_strdup(sender);
	user_record->serv_adapter = serv_adapter;
	user_record->listener_id = g_dbus_add_disconnect_watch(conn, sender,
					exit_callback, user_record, NULL);

	serv_adapter->records = g_slist_append(serv_adapter->records,
								user_record);

	DBG("listener_id %d", user_record->listener_id);

	*handle = user_record->handle;

	return 0;
}
Example #12
0
static DBusMessage *update_record(DBusMessage *msg,
				struct service_adapter *serv_adapter,
				dbus_uint32_t handle, sdp_record_t *sdp_record)
{
	int err;

	if (remove_record_from_server(handle) < 0) {
		sdp_record_free(sdp_record);
		return btd_error_not_available(msg);
	}

	sdp_record->handle = handle;
	err = add_record_to_server(get_address(serv_adapter), sdp_record);
	if (err < 0) {
		sdp_record_free(sdp_record);
		error("Failed to update the service record");
		return btd_error_failed(msg, strerror(-err));
	}

	return dbus_message_new_method_return(msg);
}
Example #13
0
static uint16_t ext_register_record(struct ext_profile *ext,
							const bdaddr_t *src)
{
	sdp_record_t *rec;

	if (ext->record)
		rec = sdp_xml_parse_record(ext->record, strlen(ext->record));
	else
		rec = ext_get_record(ext);

	if (!rec)
		return 0;

	if (add_record_to_server(src, rec) < 0) {
		error("Failed to register service record");
		sdp_record_free(rec);
		return 0;
	}

	return rec->handle;
}
Example #14
0
int avrcp_init(DBusConnection *conn, GKeyFile *config)
{
	sdp_record_t *record;
	gboolean tmp, master = TRUE;
	GError *err = NULL;

	if (avctp_server)
		return 0;

	if (config) {
		tmp = g_key_file_get_boolean(config, "General",
							"Master", &err);
		if (err) {
			debug("audio.conf: %s", err->message);
			g_error_free(err);
			err = NULL;
		} else
			master = tmp;

		input_device_name = g_key_file_get_string(config,
			"AVRCP", "InputDeviceName", &err);
		if (err) {
			debug("InputDeviceName not specified in audio.conf");
			input_device_name = NULL;
			g_error_free(err);
		}
	}

	connection = dbus_connection_ref(conn);

	record = avrcp_tg_record();
	if (!record) {
		error("Unable to allocate new service record");
		return -1;
	}

	if (add_record_to_server(BDADDR_ANY, record) < 0) {
		error("Unable to register AVRCP target service record");
		sdp_record_free(record);
		return -1;
	}
	tg_record_id = record->handle;

#ifndef ANDROID
	record = avrcp_ct_record();
	if (!record) {
		error("Unable to allocate new service record");
		return -1;
	}

	if (add_record_to_server(BDADDR_ANY, record) < 0) {
		error("Unable to register AVRCP controller service record");
		sdp_record_free(record);
		return -1;
	}
	ct_record_id = record->handle;
#endif

	avctp_server = avctp_server_socket(master);
	if (!avctp_server)
		return -1;

	return 0;
}
Example #15
0
static int headset_server_init(struct audio_adapter *adapter)
{
	uint8_t chan = DEFAULT_HS_AG_CHANNEL;
	sdp_record_t *record;
	gboolean master = TRUE;
	GError *err = NULL;
	uint32_t features;
	GIOChannel *io;
	bdaddr_t src;

	if (config) {
		gboolean tmp;

		tmp = g_key_file_get_boolean(config, "General", "Master",
						&err);
		if (err) {
			DBG("audio.conf: %s", err->message);
			g_clear_error(&err);
		} else
			master = tmp;
	}

	adapter_get_address(adapter->btd_adapter, &src);

	io =  bt_io_listen(BT_IO_RFCOMM, NULL, ag_confirm, adapter, NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, &src,
				BT_IO_OPT_CHANNEL, chan,
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
				BT_IO_OPT_MASTER, master,
				BT_IO_OPT_INVALID);
	if (!io)
		goto failed;

	adapter->hsp_ag_server = io;

	record = hsp_ag_record(chan);
	if (!record) {
		error("Unable to allocate new service record");
		goto failed;
	}

	if (add_record_to_server(&src, record) < 0) {
		error("Unable to register HS AG service record");
		sdp_record_free(record);
		goto failed;
	}
	adapter->hsp_ag_record_id = record->handle;

	features = headset_config_init(config);

	if (!enabled.hfp)
		return 0;

	chan = DEFAULT_HF_AG_CHANNEL;

	io = bt_io_listen(BT_IO_RFCOMM, NULL, ag_confirm, adapter, NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, &src,
				BT_IO_OPT_CHANNEL, chan,
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
				BT_IO_OPT_MASTER, master,
				BT_IO_OPT_INVALID);
	if (!io)
		goto failed;

	adapter->hfp_ag_server = io;

	record = hfp_ag_record(chan, features);
	if (!record) {
		error("Unable to allocate new service record");
		goto failed;
	}

	if (add_record_to_server(&src, record) < 0) {
		error("Unable to register HF AG service record");
		sdp_record_free(record);
		goto failed;
	}
	adapter->hfp_ag_record_id = record->handle;

	return 0;

failed:
	if (err) {
		error("%s", err->message);
		g_error_free(err);
	}

	if (adapter->hsp_ag_server) {
		g_io_channel_shutdown(adapter->hsp_ag_server, TRUE, NULL);
		g_io_channel_unref(adapter->hsp_ag_server);
		adapter->hsp_ag_server = NULL;
	}

	if (adapter->hfp_ag_server) {
		g_io_channel_shutdown(adapter->hfp_ag_server, TRUE, NULL);
		g_io_channel_unref(adapter->hfp_ag_server);
		adapter->hfp_ag_server = NULL;
	}

	return -1;
}
Example #16
0
int sap_server_register(const char *path, bdaddr_t *src)
{
	sdp_record_t *record = NULL;
	GError *gerr = NULL;
	GIOChannel *io;

	if (sap_init() < 0) {
		error("Sap driver initialization failed.");
		return -1;
	}

	server = g_try_new0(struct sap_server, 1);
	if (!server) {
		sap_exit();
		return -ENOMEM;
	}

	server->path = g_strdup(path);

	record = create_sap_record(SAP_SERVER_CHANNEL);
	if (!record) {
		error("Creating SAP SDP record failed.");
		goto sdp_err;
	}

	if (add_record_to_server(src, record) < 0) {
		error("Adding SAP SDP record to the SDP server failed.");
		sdp_record_free(record);
		goto sdp_err;
	}

	server->record_id = record->handle;

	io = bt_io_listen(BT_IO_RFCOMM, NULL, connect_confirm_cb, server,
			NULL, &gerr,
			BT_IO_OPT_SOURCE_BDADDR, src,
			BT_IO_OPT_CHANNEL, SAP_SERVER_CHANNEL,
			BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_HIGH,
			BT_IO_OPT_MASTER, TRUE,
			BT_IO_OPT_INVALID);
	if (!io) {
		error("Can't listen at channel %d.", SAP_SERVER_CHANNEL);
		g_error_free(gerr);
		goto server_err;
	}

	DBG("Listen socket 0x%02x", g_io_channel_unix_get_fd(io));

	server->listen_io = io;
	server->conn = NULL;

	if (!g_dbus_register_interface(connection, path, SAP_SERVER_INTERFACE,
					server_methods, server_signals, NULL,
					server, destroy_sap_interface)) {
		error("D-Bus failed to register %s interface",
							SAP_SERVER_INTERFACE);
		goto server_err;
	}

	return 0;

server_err:
	remove_record_from_server(server->record_id);
sdp_err:
	server_free(server);
	sap_exit();

	return -1;
}
Example #17
0
gboolean mcap_update_sdp_record(struct mcap_adapter *adapter, GSList *app_list)
{ DBG("");
DBG("1");
	sdp_record_t *sdp_record;
	bdaddr_t addr;

	if (adapter->sdp_handler)
		remove_record_from_server(adapter->sdp_handler);

	if (!app_list) {
		adapter->sdp_handler = 0;
		return TRUE;
	}
	DBG("3");

	sdp_record = sdp_record_alloc();
	if (!sdp_record)
		return FALSE;

	if (adapter->sdp_handler)
		sdp_record->handle = adapter->sdp_handler;
	else
		sdp_record->handle = 0xffffffff; 
	DBG("4");

	if (is_app_role(app_list, MCAP_SINK))
		set_sdp_services_uuid(sdp_record, MCAP_SINK);
	if (is_app_role(app_list, MCAP_SOURCE))
		set_sdp_services_uuid(sdp_record, MCAP_SOURCE);
	DBG("52");

	if (!register_service_protocols(adapter, sdp_record))
	DBG("eq");
	if (!register_service_profiles(sdp_record))
	DBG("e2");
	if (!register_service_additional_protocols(adapter, sdp_record))
		DBG("e3");
	DBG("5");

	sdp_set_info_attr(sdp_record, MCAP_SERVICE_NAME, MCAP_SERVICE_PROVIDER,
							MCAP_SERVICE_DSC);
	if (!register_service_sup_features(app_list, sdp_record))
		DBG("e4");
	if (!register_data_exchange_spec(sdp_record))
	DBG("45");
	DBG("6");

	register_mcap_features(sdp_record);

	if (sdp_set_record_state(sdp_record, adapter->record_state++))
	DBG("5");

	adapter_get_address(adapter->btd_adapter, &addr);
	DBG("8");

	if (add_record_to_server(&addr, sdp_record) < 0)
	DBG("5");
	DBG("7");
	adapter->sdp_handler = sdp_record->handle;
	return TRUE;

fail:
	if (sdp_record)
		sdp_record_free(sdp_record);
	
	return TRUE;
}
Example #18
0
int avrcp_register(DBusConnection *conn, const bdaddr_t *src, GKeyFile *config)
{
	sdp_record_t *record;
	gboolean tmp, master = TRUE;
	GError *err = NULL;
	struct avctp_server *server;

	if (config) {
		tmp = g_key_file_get_boolean(config, "General",
							"Master", &err);
		if (err) {
			DBG("audio.conf: %s", err->message);
			g_error_free(err);
		} else
			master = tmp;
		err = NULL;
		input_device_name = g_key_file_get_string(config,
			"AVRCP", "InputDeviceName", &err);
		if (err) {
			DBG("audio.conf: %s", err->message);
			input_device_name = NULL;
			g_error_free(err);
		}
	}

	server = g_new0(struct avctp_server, 1);
	if (!server)
		return -ENOMEM;

	if (!connection)
		connection = dbus_connection_ref(conn);

	record = avrcp_tg_record();
	if (!record) {
		error("Unable to allocate new service record");
		g_free(server);
		return -1;
	}

	if (add_record_to_server(src, record) < 0) {
		error("Unable to register AVRCP target service record");
		g_free(server);
		sdp_record_free(record);
		return -1;
	}
	server->tg_record_id = record->handle;

#ifndef ANDROID
	record = avrcp_ct_record();
	if (!record) {
		error("Unable to allocate new service record");
		g_free(server);
		return -1;
	}

	if (add_record_to_server(src, record) < 0) {
		error("Unable to register AVRCP controller service record");
		sdp_record_free(record);
		g_free(server);
		return -1;
	}
	server->ct_record_id = record->handle;
#endif

	server->io = avctp_server_socket(src, master);
	if (!server->io) {
#ifndef ANDROID
		remove_record_from_server(server->ct_record_id);
#endif
		remove_record_from_server(server->tg_record_id);
		g_free(server);
		return -1;
	}

	bacpy(&server->src, src);

	servers = g_slist_append(servers, server);

	return 0;
}