/* snd_utils.c
**
** Copyright (c) 2019, The Linux Foundation. All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above
**     copyright notice, this list of conditions and the following
**     disclaimer in the documentation and/or other materials provided
**     with the distribution.
**   * Neither the name of The Linux Foundation nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
** ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
** BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
** BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
** OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
** IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**/

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include "snd_utils.h"

#define SND_DLSYM(h, p, s, err) \
do {                            \
	err = 0;                    \
	p = dlsym(h, s);            \
	if (!p)                     \
		err = -ENODEV;          \
} while(0)

int snd_utils_get_int(struct snd_node *node, const char *prop, int *val)
{
	if (!node || !node->card_node || !node->dev_node)
		return SND_NODE_TYPE_HW;

	return node->get_int(node->dev_node, prop, val);
}

int snd_utils_get_str(struct snd_node *node, const char *prop, char **val)
{
	if (!node || !node->card_node || !node->dev_node)
		return SND_NODE_TYPE_HW;

	return node->get_str(node->dev_node, prop, val);
}

void snd_utils_put_dev_node(struct snd_node *node)
{
	if (!node)
		return;

	if (node->card_node)
		node->put_card(node->card_node);

	if (node->dl_hdl)
		dlclose(node->dl_hdl);

	free(node);
}

enum snd_node_type snd_utils_get_node_type(struct snd_node *node)
{
	int val = SND_NODE_TYPE_HW;

	if (!node || !node->card_node || !node->dev_node)
		return SND_NODE_TYPE_HW;

	node->get_int(node->dev_node, "type", &val);

	return val;
};


static int snd_utils_resolve_symbols(struct snd_node *node)
{
	void *dl = node->dl_hdl;
	int err;

	SND_DLSYM(dl, node->get_card, "snd_card_def_get_card", err);
	if (err)
		goto done;
	SND_DLSYM(dl, node->put_card, "snd_card_def_put_card", err);
	if (err)
		goto done;
	SND_DLSYM(dl, node->get_node, "snd_card_def_get_node", err);
	if (err)
		goto done;
	SND_DLSYM(dl, node->get_int, "snd_card_def_get_int", err);
	if (err)
		goto done;
	SND_DLSYM(dl, node->get_str, "snd_card_def_get_str", err);

done:
	return err;
}

struct snd_node *snd_utils_get_dev_node(unsigned int card,
		unsigned int device, int dev_type)
{
	struct snd_node *node;
	int rc = 0;

	node = calloc(1, sizeof(*node));
	if (!node)
		return NULL;

	node->dl_hdl = dlopen("libsndcardparser.so", RTLD_NOW);
	if (!node->dl_hdl) {
		goto err_dl_open;
	}

	rc = snd_utils_resolve_symbols(node);
	if (rc < 0)
		goto err_resolve_symbols;

	node->card_node = node->get_card(card);
	if (!node->card_node)
		goto err_resolve_symbols;

	node->dev_node = node->get_node(node->card_node,
					device, dev_type);
	if (!node->dev_node)
		goto err_get_node;

	return node;

err_get_node:
	node->put_card(node->card_node);

err_resolve_symbols:
	dlclose(node->dl_hdl);

err_dl_open:
	free(node);
	return NULL;
}
