Пример #1
0
static void agent_disconnect(struct audio_device *dev, struct hf_agent *agent)
{
	DBusMessage *msg;

	msg = dbus_message_new_method_call(agent->name, agent->path,
			"org.bluez.HandsfreeAgent", "Release");

	g_dbus_send_message(btd_get_dbus_connection(), msg);

	agent_cancel(agent);
}
Пример #2
0
static void simple_agent_reply(DBusPendingCall *call, void *user_data)
{
	struct agent_request *req = user_data;
	struct agent *agent = req->agent;
	DBusMessage *message;
	DBusError err;
	agent_cb cb = req->cb;

	/* steal_reply will always return non-NULL since the callback
	 * is only called after a reply has been received */
	message = dbus_pending_call_steal_reply(call);

	dbus_error_init(&err);
	if (dbus_set_error_from_message(&err, message)) {
		if ((g_str_equal(DBUS_ERROR_UNKNOWN_METHOD, err.name) ||
				g_str_equal(DBUS_ERROR_NO_REPLY, err.name)) &&
				request_fallback(req, simple_agent_reply) == 0) {
			dbus_error_free(&err);
			return;
		}

		error("Agent replied with an error: %s, %s",
				err.name, err.message);

		cb(agent, &err, req->user_data);

		if (dbus_error_has_name(&err, DBUS_ERROR_NO_REPLY)) {
			agent_cancel(agent);
			dbus_message_unref(message);
			dbus_error_free(&err);
			return;
		}

		dbus_error_free(&err);
		goto done;
	}

	dbus_error_init(&err);
	if (!dbus_message_get_args(message, &err, DBUS_TYPE_INVALID)) {
		error("Wrong reply signature: %s", err.message);
		cb(agent, &err, req->user_data);
		dbus_error_free(&err);
		goto done;
	}

	cb(agent, NULL, req->user_data);
done:
	dbus_message_unref(message);

	agent->request = NULL;
	agent_request_free(req, TRUE);
}
Пример #3
0
static void simple_agent_reply(DBusPendingCall *call, void *user_data)
{
	struct agent_request *req = user_data;
	struct agent *agent = req->agent;
	DBusMessage *message;
	DBusError err;
	agent_cb cb = req->cb;

	/* steal_reply will always return non-NULL since the callback
	 * is only called after a reply has been received */
	message = dbus_pending_call_steal_reply(call);

	dbus_error_init(&err);
	if (dbus_set_error_from_message(&err, message)) {
		error("Agent replied with an error: %s, %s",
				err.name, err.message);

		cb(agent, &err, req->user_data);

		if (dbus_error_has_name(&err, DBUS_ERROR_NO_REPLY)) {
			agent_cancel(agent);
			dbus_message_unref(message);
			dbus_error_free(&err);
			return;
		}
// +s LGBT_COMMON_TEMPORARY [email protected] 120829
		if (dbus_error_has_name(&err, "org.bluez.Error.Canceled")) {
			DBG("User cancel the pairing");
			DBG("->device_set_temporary");
			device_set_temporary(((struct authentication_req*) req->user_data)->device, TRUE);
		}
// +e LGBT_COMMON_TEMPORARY	
		dbus_error_free(&err);
		goto done;
	}

	dbus_error_init(&err);
	if (!dbus_message_get_args(message, &err, DBUS_TYPE_INVALID)) {
		error("Wrong reply signature: %s", err.message);
		cb(agent, &err, req->user_data);
		dbus_error_free(&err);
		goto done;
	}

	cb(agent, NULL, req->user_data);
done:
	dbus_message_unref(message);

	agent->request = NULL;
	agent_request_free(req, TRUE);
}
Пример #4
0
static void simple_agent_reply(DBusPendingCall *call, void *user_data)
{
	struct agent_request *req = user_data;
	struct agent *agent = req->agent;
	DBusMessage *message;
	DBusError err;
	agent_cb cb = req->cb;

	/* steal_reply will always return non-NULL since the callback
	 * is only called after a reply has been received */
	message = dbus_pending_call_steal_reply(call);

	/* Protect from the callback freeing the agent */
	agent_ref(agent);

	dbus_error_init(&err);
	if (dbus_set_error_from_message(&err, message)) {
		DBG("agent error reply: %s, %s", err.name, err.message);

		cb(agent, &err, req->user_data);

		if (dbus_error_has_name(&err, DBUS_ERROR_NO_REPLY)) {
			error("Timed out waiting for reply from agent");
			agent_cancel(agent);
			dbus_message_unref(message);
			dbus_error_free(&err);
			agent_unref(agent);
			return;
		}

		dbus_error_free(&err);
		goto done;
	}

	if (!dbus_message_get_args(message, &err, DBUS_TYPE_INVALID)) {
		error("Wrong reply signature: %s", err.message);
		cb(agent, &err, req->user_data);
		dbus_error_free(&err);
		goto done;
	}

	cb(agent, NULL, req->user_data);
done:
	dbus_message_unref(message);

	agent->request = NULL;
	agent_request_free(req, TRUE);
	agent_unref(agent);
}
Пример #5
0
static void display_pincode_reply(DBusPendingCall *call, void *user_data)
{
	struct agent_request *req = user_data;
	struct agent *agent = req->agent;
	DBusMessage *message;
	DBusError err;
	agent_cb cb = req->cb;

	/* clear agent->request early; our callback will likely try
	 * another request */
	agent->request = NULL;

	/* steal_reply will always return non-NULL since the callback
	 * is only called after a reply has been received */
	message = dbus_pending_call_steal_reply(call);

	dbus_error_init(&err);
	if (dbus_set_error_from_message(&err, message)) {
		error("Agent replied with an error: %s, %s",
						err.name, err.message);

		cb(agent, &err, req->user_data);

		if (dbus_error_has_name(&err, DBUS_ERROR_NO_REPLY)) {
			agent_cancel(agent);
			dbus_message_unref(message);
			dbus_error_free(&err);
			return;
		}

		dbus_error_free(&err);
		goto done;
	}

	if (!dbus_message_get_args(message, &err, DBUS_TYPE_INVALID)) {
		error("Wrong reply signature: %s", err.message);
		cb(agent, &err, req->user_data);
		dbus_error_free(&err);
		goto done;
	}

	cb(agent, NULL, req->user_data);
done:
	dbus_message_unref(message);

	agent_request_free(req, TRUE);
}
Пример #6
0
void agent_unref(struct agent *agent)
{
	agent->ref--;

	DBG("%p: ref=%d", agent, agent->ref);

	if (agent->ref > 0)
		return;

	if (agent->request) {
		DBusError err;
		agent_pincode_cb pincode_cb;
		agent_passkey_cb passkey_cb;
		agent_cb cb;

		dbus_error_init(&err);
		dbus_set_error_const(&err, ERROR_INTERFACE ".Failed",
								"Canceled");

		switch (agent->request->type) {
		case AGENT_REQUEST_PINCODE:
			pincode_cb = agent->request->cb;
			pincode_cb(agent, &err, NULL, agent->request->user_data);
			break;
		case AGENT_REQUEST_PASSKEY:
			passkey_cb = agent->request->cb;
			passkey_cb(agent, &err, 0, agent->request->user_data);
			break;
		case AGENT_REQUEST_CONFIRMATION:
		case AGENT_REQUEST_AUTHORIZATION:
		case AGENT_REQUEST_AUTHORIZE_SERVICE:
		case AGENT_REQUEST_DISPLAY_PINCODE:
		default:
			cb = agent->request->cb;
			cb(agent, &err, agent->request->user_data);
		}

		dbus_error_free(&err);

		agent_cancel(agent);
	}

	g_free(agent->owner);
	g_free(agent->path);

	g_free(agent);
}
Пример #7
0
void agent_free(struct agent *agent)
{
	if (!agent)
		return;

	if (agent->remove_cb)
		agent->remove_cb(agent, agent->remove_cb_data);

	if (agent->request) {
		DBusError err;
		agent_pincode_cb pincode_cb;
		agent_passkey_cb passkey_cb;
		agent_cb cb;

		dbus_error_init(&err);
		dbus_set_error_const(&err, "org.bluez.Error.Failed", "Canceled");

		switch (agent->request->type) {
		case AGENT_REQUEST_PINCODE:
			pincode_cb = agent->request->cb;
			pincode_cb(agent, &err, NULL, agent->request->user_data);
			break;
		case AGENT_REQUEST_PASSKEY:
			passkey_cb = agent->request->cb;
			passkey_cb(agent, &err, 0, agent->request->user_data);
			break;
		default:
			cb = agent->request->cb;
			cb(agent, &err, agent->request->user_data);
		}

		dbus_error_free(&err);

		agent_cancel(agent);
	}

	if (!agent->exited) {
		g_dbus_remove_watch(btd_get_dbus_connection(),
							agent->listener_id);
		agent_release(agent);
	}

	g_free(agent->name);
	g_free(agent->path);

	g_free(agent);
}
Пример #8
0
static void agent_reply(DBusPendingCall *call, void *user_data)
{
	DBusMessage *reply = dbus_pending_call_steal_reply(call);
	const char *name;
	DBusError derr;
	gboolean *got_reply = user_data;

	*got_reply = TRUE;

	/* Received a reply after the agent exited */
	if (!agent)
		return;

	agent->auth_pending = FALSE;

	dbus_error_init(&derr);
	if (dbus_set_error_from_message(&derr, reply)) {
		error("Agent replied with an error: %s, %s",
				derr.name, derr.message);

		if (dbus_error_has_name(&derr, DBUS_ERROR_NO_REPLY))
			agent_cancel();

		dbus_error_free(&derr);
		dbus_message_unref(reply);
		return;
	}

	if (dbus_message_get_args(reply, NULL,
				DBUS_TYPE_STRING, &name,
				DBUS_TYPE_INVALID)) {
		/* Splits folder and name */
		const char *slash = strrchr(name, '/');
		DBG("Agent replied with %s", name);
		if (!slash) {
			agent->new_name = g_strdup(name);
			agent->new_folder = NULL;
		} else {
			agent->new_name = g_strdup(slash + 1);
			agent->new_folder = g_strndup(name, slash - name);
		}
	}

	dbus_message_unref(reply);
}
Пример #9
0
static void agent_release(struct agent *agent)
{
	DBusMessage *message;

	DBG("Releasing agent %s, %s", agent->name, agent->path);

	if (agent->request)
		agent_cancel(agent);

	message = dbus_message_new_method_call(agent->name, agent->path,
			"org.bluez.Agent", "Release");
	if (message == NULL) {
		error("Couldn't allocate D-Bus message");
		return;
	}

	g_dbus_send_message(connection, message);
}
Пример #10
0
static void agent_release(struct agent *agent)
{
	DBusMessage *message;

	DBG("Releasing agent %s, %s", agent->owner, agent->path);

	if (agent->request)
		agent_cancel(agent);

	message = dbus_message_new_method_call(agent->owner, agent->path,
						AGENT_INTERFACE, "Release");
	if (message == NULL) {
		error("Couldn't allocate D-Bus message");
		return;
	}

	g_dbus_send_message(btd_get_dbus_connection(), message);
}
Пример #11
0
int gateway_close(struct audio_device *device)
{
	GError *gerr = NULL;
	struct gateway *gw = device->gateway;
	int sock;

	if (gw->rfcomm_id != 0) {
		g_source_remove(gw->rfcomm_id);
		gw->rfcomm_id = 0;
	}

	if (gw->sco_id != 0) {
		g_source_remove(gw->sco_id);
		gw->sco_id = 0;
	}

	if (gw->rfcomm) {
		sock = g_io_channel_unix_get_fd(gw->rfcomm);
		shutdown(sock, SHUT_RDWR);

		g_io_channel_shutdown(gw->rfcomm, TRUE, NULL);
		g_io_channel_unref(gw->rfcomm);
		gw->rfcomm = NULL;
	}

	if (gw->sco) {
		g_io_channel_shutdown(gw->sco, TRUE, NULL);
		g_io_channel_unref(gw->sco);
		gw->sco = NULL;
	}

	if (gw->agent)
		agent_cancel(gw->agent);

	change_state(device, GATEWAY_STATE_DISCONNECTED);
	g_set_error(&gerr, GATEWAY_ERROR,
			GATEWAY_ERROR_DISCONNECTED, "Disconnected");
	run_connect_cb(device, gerr);
	g_error_free(gerr);

	return 0;
}
Пример #12
0
int manager_request_authorization(struct obex_transfer *transfer, int32_t time,
					char **new_folder, char **new_name)
{
	struct obex_session *os = transfer->session;
	DBusMessage *msg;
	DBusPendingCall *call;
	unsigned int watch;
	gboolean got_reply;

	if (!agent)
		return -1;

	if (agent->auth_pending)
		return -EPERM;

	if (!new_folder || !new_name)
		return -EINVAL;

	msg = dbus_message_new_method_call(agent->bus_name, agent->path,
							AGENT_INTERFACE,
							"AuthorizePush");

	dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &transfer->path,
							DBUS_TYPE_INVALID);

	if (!g_dbus_send_message_with_reply(connection, msg, &call, TIMEOUT)) {
		dbus_message_unref(msg);
		return -EPERM;
	}

	dbus_message_unref(msg);

	agent->auth_pending = TRUE;
	got_reply = FALSE;

	/* Catches errors before authorization response comes */
	watch = g_io_add_watch_full(os->io, G_PRIORITY_DEFAULT,
			G_IO_HUP | G_IO_ERR | G_IO_NVAL,
			auth_error, NULL, NULL);

	dbus_pending_call_set_notify(call, agent_reply, &got_reply, NULL);

	/* Workaround: process events while agent doesn't reply */
	while (agent && agent->auth_pending)
		g_main_context_iteration(NULL, TRUE);

	g_source_remove(watch);

	if (!got_reply) {
		dbus_pending_call_cancel(call);
		agent_cancel();
	}

	dbus_pending_call_unref(call);

	if (!agent || !agent->new_name)
		return -EPERM;

	*new_folder = agent->new_folder;
	*new_name = agent->new_name;
	agent->new_folder = NULL;
	agent->new_name = NULL;

	return 0;
}
Пример #13
0
int manager_request_authorization(struct obex_session *os, int32_t time,
					char **new_folder, char **new_name)
{
	DBusMessage *msg;
	DBusPendingCall *call;
	const char *filename = os->name ? os->name : "";
	const char *type = os->type ? os->type : "";
	char *path, *address;
	unsigned int watch;
	gboolean got_reply;
	int err;

	if (!agent)
		return -1;

	if (agent->auth_pending)
		return -EPERM;

	if (!new_folder || !new_name)
		return -EINVAL;

	err = obex_getpeername(os, &address);
	if (err < 0)
		return err;

	path = g_strdup_printf("/transfer%u", os->id);

	msg = dbus_message_new_method_call(agent->bus_name, agent->path,
						AGENT_INTERFACE, "Authorize");

	dbus_message_append_args(msg,
			DBUS_TYPE_OBJECT_PATH, &path,
			DBUS_TYPE_STRING, &address,
			DBUS_TYPE_STRING, &filename,
			DBUS_TYPE_STRING, &type,
			DBUS_TYPE_INT32, &os->size,
			DBUS_TYPE_INT32, &time,
			DBUS_TYPE_INVALID);

	g_free(path);
	g_free(address);

	if (!dbus_connection_send_with_reply(connection,
					msg, &call, TIMEOUT)) {
		dbus_message_unref(msg);
		return -EPERM;
	}

	dbus_message_unref(msg);

	agent->auth_pending = TRUE;
	got_reply = FALSE;

	/* Catches errors before authorization response comes */
	watch = g_io_add_watch_full(os->io, G_PRIORITY_DEFAULT,
			G_IO_HUP | G_IO_ERR | G_IO_NVAL,
			auth_error, NULL, NULL);

	dbus_pending_call_set_notify(call, agent_reply, &got_reply, NULL);

	/* Workaround: process events while agent doesn't reply */
	while (agent && agent->auth_pending)
		g_main_context_iteration(NULL, TRUE);

	g_source_remove(watch);

	if (!got_reply) {
		dbus_pending_call_cancel(call);
		agent_cancel();
	}

	dbus_pending_call_unref(call);

	if (!agent || !agent->new_name)
		return -EPERM;

	*new_folder = agent->new_folder;
	*new_name = agent->new_name;
	agent->new_folder = NULL;
	agent->new_name = NULL;

	return 0;
}