/*
 * QEMU Random Number Generator Backend
 *
 * Copyright IBM, Corp. 2012
 *
 * Authors:
 *  Anthony Liguori   <aliguori@us.ibm.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "sysemu/rng.h"
#include "qapi/error.h"
#include "qemu/module.h"
#include "qom/object_interfaces.h"

void rng_backend_request_entropy(RngBackend *s, size_t size,
                                 EntropyReceiveFunc *receive_entropy,
                                 void *opaque)
{
    RngBackendClass *k = RNG_BACKEND_GET_CLASS(s);
    RngRequest *req;

    if (k->request_entropy) {
        req = g_malloc(sizeof(*req));

        req->offset = 0;
        req->size = size;
        req->receive_entropy = receive_entropy;
        req->opaque = opaque;
        req->data = g_malloc(req->size);

        k->request_entropy(s, req);

        QSIMPLEQ_INSERT_TAIL(&s->requests, req, next);
    }
}

static bool rng_backend_prop_get_opened(Object *obj, Error **errp)
{
    RngBackend *s = RNG_BACKEND(obj);

    return s->opened;
}

static void rng_backend_complete(UserCreatable *uc, Error **errp)
{
    RngBackend *s = RNG_BACKEND(uc);
    RngBackendClass *k = RNG_BACKEND_GET_CLASS(s);
    Error *local_err = NULL;

    if (k->opened) {
        k->opened(s, &local_err);
        if (local_err) {
            error_propagate(errp, local_err);
            return;
        }
    }

    s->opened = true;
}

static void rng_backend_free_request(RngRequest *req)
{
    g_free(req->data);
    g_free(req);
}

static void rng_backend_free_requests(RngBackend *s)
{
    RngRequest *req, *next;

    QSIMPLEQ_FOREACH_SAFE(req, &s->requests, next, next) {
        rng_backend_free_request(req);
    }

    QSIMPLEQ_INIT(&s->requests);
}

void rng_backend_finalize_request(RngBackend *s, RngRequest *req)
{
    QSIMPLEQ_REMOVE(&s->requests, req, RngRequest, next);
    rng_backend_free_request(req);
}

static void rng_backend_init(Object *obj)
{
    RngBackend *s = RNG_BACKEND(obj);

    QSIMPLEQ_INIT(&s->requests);
}

static void rng_backend_finalize(Object *obj)
{
    RngBackend *s = RNG_BACKEND(obj);

    rng_backend_free_requests(s);
}

static void rng_backend_class_init(ObjectClass *oc, void *data)
{
    UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);

    ucc->complete = rng_backend_complete;

    object_class_property_add_bool(oc, "opened",
                                   rng_backend_prop_get_opened,
                                   NULL);
}

static const TypeInfo rng_backend_info = {
    .name = TYPE_RNG_BACKEND,
    .parent = TYPE_OBJECT,
    .instance_size = sizeof(RngBackend),
    .instance_init = rng_backend_init,
    .instance_finalize = rng_backend_finalize,
    .class_size = sizeof(RngBackendClass),
    .class_init = rng_backend_class_init,
    .abstract = true,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_USER_CREATABLE },
        { }
    }
};

static void register_types(void)
{
    type_register_static(&rng_backend_info);
}

type_init(register_types);
