示例#1
0
static void confirm_agent_reply(DBusPendingCall *call, void *user_data)
{
	struct pending_agent_request *req = user_data;
	struct passkey_agent *agent = req->agent;
	pin_code_reply_cp pr;
	DBusMessage *message;
	DBusError err;
	int len;

	/* 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("Passkey agent replied with an error: %s, %s",
				err.name, err.message);

		dbus_error_free(&err);
		goto fail;
	}

	dbus_error_init(&err);
	if (!dbus_message_get_args(message, &err, DBUS_TYPE_INVALID)) {
		error("Wrong confirm reply signature: %s", err.message);
		dbus_error_free(&err);
		goto fail;
	}

	len = strlen(req->pin);

	set_pin_length(&req->sba, len);

	memset(&pr, 0, sizeof(pr));
	bacpy(&pr.bdaddr, &req->bda);
	memcpy(pr.pin_code, req->pin, len);
	pr.pin_len = len;
	hci_send_cmd(req->dev, OGF_LINK_CTL,
			OCF_PIN_CODE_REPLY, PIN_CODE_REPLY_CP_SIZE, &pr);

	goto done;

fail:
	hci_send_cmd(req->dev, OGF_LINK_CTL,
			OCF_PIN_CODE_NEG_REPLY, 6, &req->bda);

done:
	if (message)
		dbus_message_unref(message);

	agent->pending_requests = g_slist_remove(agent->pending_requests, req);
	dbus_pending_call_cancel(req->call);
	if (req->call)
		dbus_pending_call_unref(req->call);
	g_free(req->pin);
	g_free(req->path);
	g_free(req);

	if (agent != default_agent) {
		agent->adapter->passkey_agents = g_slist_remove(agent->adapter->passkey_agents,
								agent);
		passkey_agent_free(agent);
	}
}
示例#2
0
static void passkey_agent_reply(DBusPendingCall *call, void *user_data)
{
	struct pending_agent_request *req = user_data;
	struct passkey_agent *agent = req->agent;
	pin_code_reply_cp pr;
	DBusMessage *message;
	DBusError err;
	size_t len;
	char *pin;

	/* 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 (!req->old_if && !strcmp(err.name, DBUS_ERROR_UNKNOWN_METHOD)) {
			debug("New Request API failed, trying old one");
			req->old_if = 1;
			dbus_error_free(&err);
			dbus_pending_call_unref(req->call);
			req->call = agent_request(req->path, &req->bda, agent,
							FALSE, 1);
			if (!req->call)
				goto fail;

			dbus_message_unref(message);

			dbus_pending_call_set_notify(req->call,
							passkey_agent_reply,
							req, NULL);
			return;
		}

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

		dbus_error_free(&err);
		goto fail;
	}

	dbus_error_init(&err);
	if (!dbus_message_get_args(message, &err,
				DBUS_TYPE_STRING, &pin,
				DBUS_TYPE_INVALID)) {
		error("Wrong passkey reply signature: %s", err.message);
		dbus_error_free(&err);
		goto fail;
	}

	len = strlen(pin);

	if (len > 16 || len < 1) {
		error("Invalid passkey length from handler");
		goto fail;
	}

	set_pin_length(&req->sba, len);

	memset(&pr, 0, sizeof(pr));
	bacpy(&pr.bdaddr, &req->bda);
	memcpy(pr.pin_code, pin, len);
	pr.pin_len = len;
	hci_send_cmd(req->dev, OGF_LINK_CTL,
			OCF_PIN_CODE_REPLY, PIN_CODE_REPLY_CP_SIZE, &pr);

	goto done;

fail:
	hci_send_cmd(req->dev, OGF_LINK_CTL,
			OCF_PIN_CODE_NEG_REPLY, 6, &req->bda);

done:
	if (message)
		dbus_message_unref(message);

	agent->pending_requests = g_slist_remove(agent->pending_requests, req);
	dbus_pending_call_cancel(req->call);
	if (req->call)
		dbus_pending_call_unref(req->call);
	g_free(req->path);
	g_free(req);

	if (agent != default_agent) {
		agent->adapter->passkey_agents = g_slist_remove(agent->adapter->passkey_agents,
								agent);
		passkey_agent_free(agent);
	}
}
示例#3
0
static void pincode_reply(DBusPendingCall *call, void *user_data)
{
	struct agent_request *req = user_data;
	struct agent *agent = req->agent;
	struct btd_adapter *adapter = agent->adapter;
	agent_pincode_cb cb = req->cb;
	DBusMessage *message;
	DBusError err;
	bdaddr_t sba;
	size_t len;
	char *pin;

	adapter_get_address(adapter, &sba);

	/* 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, pincode_reply) == 0) {
			dbus_error_free(&err);
			return;
		}

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

		cb(agent, &err, NULL, req->user_data);
		dbus_error_free(&err);
		goto done;
	}

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

	len = strlen(pin);

	dbus_error_init(&err);
	if (len > 16 || len < 1) {
		error("Invalid passkey length from handler");
		dbus_set_error_const(&err, "org.bluez.Error.InvalidArgs",
					"Invalid passkey length");
		cb(agent, &err, NULL, req->user_data);
		dbus_error_free(&err);
		goto done;
	}

	set_pin_length(&sba, len);

	cb(agent, NULL, pin, req->user_data);

done:
	if (message)
		dbus_message_unref(message);

	dbus_pending_call_cancel(req->call);
	agent->request = NULL;
	agent_request_free(req, TRUE);
}