Beispiel #1
0
static void connection_destroy(DBusConnection *conn, void *user_data)
{
	struct network_conn *nc = user_data;

	if (nc->state == CONNECTED) {
		bnep_if_down(nc->dev);
		bnep_kill_connection(&nc->peer->dst);
	} else if (nc->io)
		cancel_connection(nc, NULL);
}
Beispiel #2
0
static void connection_destroy(DBusConnection *conn, void *user_data)
{
	struct network_conn *nc = user_data;

	if (nc->state == CONNECTED) {
		bnep_if_down(nc->dev);
		bnep_kill_connection(device_get_address(nc->peer->device));
	} else if (nc->io)
		cancel_connection(nc, -EIO);
}
Beispiel #3
0
static gboolean bnep_conn_req_to(gpointer user_data)
{
	struct network_conn *nc;

	nc = user_data;
	if (nc->attempt_cnt == CON_SETUP_RETRIES) {
		error("Too many bnep connection attempts");
	} else {
		error("bnep connection setup TO, retrying...");
		if (!bnep_send_conn_req(nc))
			return TRUE;
	}

	cancel_connection(nc, "bnep setup failed");

	return FALSE;
}
Beispiel #4
0
static void bnep_conn_cb(GIOChannel *chan, char *iface, int err, void *data)
{
	struct network_conn *nc = data;
	const char *path;
	DBusConnection *conn;

	DBG("");

	if (err < 0) {
		error("connect failed %s", strerror(-err));
		goto failed;
	}

	info("%s connected", nc->dev);

	memcpy(nc->dev, iface, sizeof(nc->dev));
	btd_service_connecting_complete(nc->service, 0);

	if (nc->connect)
		local_connect_cb(nc, 0);

	conn = btd_get_dbus_connection();
	path = device_get_path(nc->peer->device);

	g_dbus_emit_property_changed(conn, path,
					NETWORK_PEER_INTERFACE, "Connected");
	g_dbus_emit_property_changed(conn, path,
					NETWORK_PEER_INTERFACE, "Interface");
	g_dbus_emit_property_changed(conn, path,
					NETWORK_PEER_INTERFACE, "UUID");

	nc->state = CONNECTED;
	nc->dc_id = device_add_disconnect_watch(nc->peer->device, disconnect_cb,
								nc, NULL);
	g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
							bnep_watchdog_cb, nc);
	g_io_channel_unref(nc->io);
	nc->io = NULL;

	return;

failed:
	cancel_connection(nc, -EIO);
}
Beispiel #5
0
static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
{
	struct network_conn *nc = data;
	int perr;

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

	perr = bnep_connect(nc);
	if (perr < 0) {
		error("bnep connect(): %s (%d)", strerror(-perr), -perr);
		goto failed;
	}

	return;

failed:
	cancel_connection(nc, -EIO);
}
Beispiel #6
0
static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
{
	struct network_conn *nc = data;
	int sk, perr;

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

	sk = g_io_channel_unix_get_fd(nc->io);
	perr = bnep_connect(sk, BNEP_SVC_PANU, nc->id, bnep_conn_cb, nc);
	if (perr < 0) {
		error("bnep connect(): %s (%d)", strerror(-perr), -perr);
		goto failed;
	}

	return;

failed:
	cancel_connection(nc, -EIO);
}
Beispiel #7
0
static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
							gpointer data)
{
	struct network_conn *nc = data;
	struct bnep_control_rsp *rsp;
	struct timeval timeo;
	char pkt[BNEP_MTU];
	ssize_t r;
	int sk;
	const char *pdev, *uuid;
	gboolean connected;

	if (cond & G_IO_NVAL)
		return FALSE;

	g_source_remove(nc->timeout_source);
	nc->timeout_source = 0;

	if (cond & (G_IO_HUP | G_IO_ERR)) {
		error("Hangup or error on l2cap server socket");
		goto failed;
	}

	sk = g_io_channel_unix_get_fd(chan);

	memset(pkt, 0, BNEP_MTU);
	r = read(sk, pkt, sizeof(pkt) -1);
	if (r < 0) {
		error("IO Channel read error");
		goto failed;
	}

	if (r == 0) {
		error("No packet received on l2cap socket");
		goto failed;
	}

	errno = EPROTO;

	if ((size_t) r < sizeof(*rsp)) {
		error("Packet received is not bnep type");
		goto failed;
	}

	rsp = (void *) pkt;
	if (rsp->type != BNEP_CONTROL) {
		error("Packet received is not bnep type");
		goto failed;
	}

	if (rsp->ctrl != BNEP_SETUP_CONN_RSP)
		return TRUE;

	r = ntohs(rsp->resp);

	if (r != BNEP_SUCCESS) {
		error("bnep failed");
		goto failed;
	}

	memset(&timeo, 0, sizeof(timeo));
	timeo.tv_sec = 0;

	setsockopt(sk, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo));

	if (bnep_connadd(sk, BNEP_SVC_PANU, nc->dev)) {
		error("%s could not be added", nc->dev);
		goto failed;
	}

	bnep_if_up(nc->dev);
	pdev = nc->dev;
	uuid = bnep_uuid(nc->id);

	g_dbus_send_reply(connection, nc->msg,
			DBUS_TYPE_STRING, &pdev,
			DBUS_TYPE_INVALID);

	connected = TRUE;
	emit_property_changed(connection, nc->peer->path,
				NETWORK_PEER_INTERFACE, "Connected",
				DBUS_TYPE_BOOLEAN, &connected);
	emit_property_changed(connection, nc->peer->path,
				NETWORK_PEER_INTERFACE, "Interface",
				DBUS_TYPE_STRING, &pdev);
	emit_property_changed(connection, nc->peer->path,
				NETWORK_PEER_INTERFACE, "UUID",
				DBUS_TYPE_STRING, &uuid);

	nc->state = CONNECTED;
	nc->dc_id = device_add_disconnect_watch(nc->peer->device, disconnect_cb,
						nc, NULL);

	info("%s connected", nc->dev);
	/* Start watchdog */
	g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
			(GIOFunc) bnep_watchdog_cb, nc);
	g_io_channel_unref(nc->io);
	nc->io = NULL;

	return FALSE;

failed:
	cancel_connection(nc, "bnep setup failed");

	return FALSE;
}