int server_start(const bdaddr_t *src)
{
	struct input_server *server;
	GError *err = NULL;

	server = g_new0(struct input_server, 1);
	bacpy(&server->src, src);

	server->ctrl = bt_io_listen(connect_event_cb, NULL,
				server, NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, src,
				BT_IO_OPT_PSM, L2CAP_PSM_HIDP_CTRL,
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
				BT_IO_OPT_INVALID);
	if (!server->ctrl) {
		error("Failed to listen on control channel");
		g_error_free(err);
		g_free(server);
		return -1;
	}

	server->intr = bt_io_listen(NULL, confirm_event_cb,
				server, NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, src,
				BT_IO_OPT_PSM, L2CAP_PSM_HIDP_INTR,
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
				BT_IO_OPT_INVALID);
	if (!server->intr) {
		error("Failed to listen on interrupt channel");
		g_io_channel_unref(server->ctrl);
		g_error_free(err);
		g_free(server);
		return -1;
	}

	servers = g_slist_append(servers, server);

	return 0;
}
Ejemplo n.º 2
0
bool bt_a2dp_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode)
{
	GError *err = NULL;
	sdp_record_t *rec;

	DBG("");

	bacpy(&adapter_addr, addr);

	server = bt_io_listen(connect_cb, NULL, NULL, NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
				BT_IO_OPT_PSM, AVDTP_PSM,
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
				BT_IO_OPT_MASTER, true,
				BT_IO_OPT_INVALID);
	if (!server) {
		error("Failed to listen on AVDTP channel: %s", err->message);
		g_error_free(err);
		return false;
	}

	rec = a2dp_record();
	if (!rec) {
		error("Failed to allocate A2DP record");
		goto fail;
	}

	if (bt_adapter_add_record(rec, SVC_HINT_CAPTURING) < 0) {
		error("Failed to register A2DP record");
		sdp_record_free(rec);
		goto fail;
	}
	record_id = rec->handle;

	hal_ipc = ipc;

	ipc_register(hal_ipc, HAL_SERVICE_ID_A2DP, cmd_handlers,
						G_N_ELEMENTS(cmd_handlers));

	if (bt_audio_register(audio_disconnected))
		return true;

fail:
	g_io_channel_shutdown(server, TRUE, NULL);
	g_io_channel_unref(server);
	server = NULL;
	return false;
}
Ejemplo n.º 3
0
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);
		g_free(server);
		return -EIO;
	}

	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->server = io;
	server->record_handle = record->handle;
	bacpy(&server->src, &src);

	servers = g_slist_append(servers, server);

	return 0;

fail:
	if (io != NULL)
		g_io_channel_unref(io);
	g_free(server);
	return -EIO;
}
Ejemplo n.º 4
0
static int ext_start_servers(struct ext_profile *ext,
						struct btd_adapter *adapter)
{
	struct ext_io *server;
	BtIOConfirm confirm;
	BtIOConnect connect;
	GError *err = NULL;
	uint16_t handle;
	GIOChannel *io;

	handle = ext_register_record(ext, adapter_get_address(adapter));

	if (ext->authorize) {
		confirm = ext_confirm;
		connect = NULL;
	} else {
		confirm = NULL;
		connect = ext_direct_connect;
	}

	if (ext->psm) {
		server = g_new0(struct ext_io, 1);
		server->ext = ext;
		server->rec_handle = handle;

		io = bt_io_listen(connect, confirm, server, NULL, &err,
					BT_IO_OPT_SOURCE_BDADDR,
					adapter_get_address(adapter),
					BT_IO_OPT_PSM, ext->psm,
					BT_IO_OPT_SEC_LEVEL, ext->sec_level,
					BT_IO_OPT_INVALID);
		if (err != NULL) {
			error("L2CAP server failed for %s: %s",
						ext->name, err->message);
			g_free(server);
			g_clear_error(&err);
		} else {
			server->io = io;
			server->proto = BTPROTO_L2CAP;
			server->adapter = btd_adapter_ref(adapter);
			ext->servers = g_slist_append(ext->servers, server);
			DBG("%s listening on PSM %u", ext->name, ext->psm);
		}
	}
Ejemplo n.º 5
0
static int audio_init(void)
{
	GKeyFile *config;
	gboolean enable_sco;

	connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
	if (connection == NULL)
		return -EIO;

	config = load_config_file(CONFIGDIR "/audio.conf");

	if (unix_init() < 0) {
		error("Unable to setup unix socket");
		goto failed;
	}

	if (audio_manager_init(connection, config, &enable_sco) < 0)
		goto failed;

	if (!enable_sco)
		return 0;

	sco_server = bt_io_listen(BT_IO_SCO, sco_server_cb, NULL, NULL,
					NULL, NULL,
					BT_IO_OPT_INVALID);
	if (!sco_server) {
		error("Unable to start SCO server socket");
		goto failed;
	}

	return 0;

failed:
	audio_manager_exit();
	unix_exit();

	if (connection) {
		dbus_connection_unref(connection);
		connection = NULL;
	}

	return -EIO;
}
Ejemplo n.º 6
0
static GIOChannel *avctp_server_socket(const bdaddr_t *src, gboolean master)
{
	GError *err = NULL;
	GIOChannel *io;

	io = bt_io_listen(BT_IO_L2CAP, NULL, avctp_confirm_cb, NULL,
				NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, src,
				BT_IO_OPT_PSM, AVCTP_PSM,
				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 io;
}
Ejemplo n.º 7
0
static bool sco_listen(struct bt_sco *sco)
{
	GError *err = NULL;

	if (!sco)
		return false;

	sco->server_io = bt_io_listen(NULL, confirm_sco_cb, sco, NULL, &err,
							BT_IO_OPT_SOURCE_BDADDR,
							&sco->local_addr,
							BT_IO_OPT_INVALID);
	if (!sco->server_io) {
		error("sco: Failed to listen on SCO: %s", err->message);
		g_error_free(err);
		return false;
	}

	return true;
}
Ejemplo n.º 8
0
static int register_nap_server(void)
{
    GError *gerr = NULL;

    DBG("");

    nap_io = bt_io_listen(NULL, nap_confirm_cb, NULL, NULL, &gerr,
                          BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
                          BT_IO_OPT_PSM, BNEP_PSM,
                          BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
                          BT_IO_OPT_OMTU, BNEP_MTU,
                          BT_IO_OPT_IMTU, BNEP_MTU,
                          BT_IO_OPT_INVALID);

    if (!nap_io) {
        destroy_nap_device();
        error("%s", gerr->message);
        g_error_free(gerr);
        return -EIO;
    }

    return 0;
}
Ejemplo n.º 9
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;
}
Ejemplo n.º 10
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;
}
int sap_server_register(struct btd_adapter *adapter)
{
	sdp_record_t *record = NULL;
	GError *gerr = NULL;
	GIOChannel *io;
	struct sap_server *server;

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

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

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

	server = g_new0(struct sap_server, 1);
	server->adapter = btd_adapter_ref(adapter);
	server->record_id = record->handle;

	io = bt_io_listen(NULL, connect_confirm_cb, server,
			NULL, &gerr,
			BT_IO_OPT_SOURCE_BDADDR,
			btd_adapter_get_address(adapter),
			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;
	}
	server->listen_io = io;

	if (!g_dbus_register_interface(btd_get_dbus_connection(),
					adapter_get_path(server->adapter),
					SAP_SERVER_INTERFACE,
					server_methods, NULL,
					server_properties, server,
					destroy_sap_interface)) {
		error("D-Bus failed to register %s interface",
							SAP_SERVER_INTERFACE);
		goto server_err;
	}

	DBG("server %p, listen socket 0x%02x", server,
						g_io_channel_unix_get_fd(io));

	return 0;

server_err:
	server_remove(server);
sdp_err:
	sap_exit();

	return -1;
}