Ejemplo n.º 1
0
static DBusMessage *connection_get_properties(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct network_peer *peer = data;
	struct network_conn *nc = NULL;
	DBusMessage *reply;
	DBusMessageIter iter;
	DBusMessageIter dict;
	dbus_bool_t connected;
	const char *property;
	GSList *l;

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return NULL;

	dbus_message_iter_init_append(reply, &iter);

	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);

	/* Connected */
	for (l = peer->connections; l; l = l->next) {
		struct network_conn *tmp = l->data;

		if (tmp->state != CONNECTED)
			continue;

		nc = tmp;
		break;
	}

	connected = nc ? TRUE : FALSE;
	dict_append_entry(&dict, "Connected", DBUS_TYPE_BOOLEAN, &connected);

	/* Interface */
	property = nc ? nc->dev : "";
	dict_append_entry(&dict, "Interface", DBUS_TYPE_STRING, &property);

	/* UUID */
	property = nc ? bnep_uuid(nc->id) : "";
	dict_append_entry(&dict, "UUID", DBUS_TYPE_STRING, &property);

	dbus_message_iter_close_container(&iter, &dict);

	return reply;
}
Ejemplo n.º 2
0
static gboolean network_property_get_uuid(const GDBusPropertyTable *property,
					DBusMessageIter *iter, void *data)
{
	struct network_peer *peer = data;
	struct network_conn *nc;
	const char *uuid;

	nc = find_connection_by_state(peer->connections, CONNECTED);
	if (nc == NULL)
		return FALSE;

	uuid = bnep_uuid(nc->id);

	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &uuid);

	return TRUE;
}
Ejemplo n.º 3
0
static DBusMessage *local_connect(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct network_peer *peer = data;
	struct btd_service *service;
	struct network_conn *nc;
	const char *svc;
	const char *uuid;
	uint16_t id;
	int err;

	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &svc,
						DBUS_TYPE_INVALID) == FALSE)
		return btd_error_invalid_args(msg);

	id = bnep_service_id(svc);
	uuid = bnep_uuid(id);

	if (uuid == NULL)
		return btd_error_invalid_args(msg);

	service = btd_device_get_service(peer->device, uuid);
	if (service == NULL)
		return btd_error_not_supported(msg);

	nc = btd_service_get_user_data(service);

	if (nc->connect != NULL)
		return btd_error_busy(msg);

	err = connection_connect(nc->service);
	if (err < 0)
		return btd_error_failed(msg, strerror(-err));

	nc->connect = dbus_message_ref(msg);

	return NULL;
}
Ejemplo n.º 4
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;
}