Exemplo n.º 1
0
static int binary_file_parse(snd_ctl_elem_value_t *dst,
			      snd_ctl_elem_info_t *info,
			      const char *filepath)
{
	int err = 0;
	int fd;
	struct stat st;
	size_t sz;
	ssize_t sz_read;
	char *res;
	snd_ctl_elem_type_t type;
	unsigned int idx, count;

	type = snd_ctl_elem_info_get_type(info);
	if (type != SND_CTL_ELEM_TYPE_BYTES) {
		uc_error("only support byte type!");
		err = -EINVAL;
		return err;
	}
	fd = open(filepath, O_RDONLY);
	if (fd < 0) {
		err = -errno;
		return err;
	}
	if (stat(filepath, &st) == -1) {
		err = -errno;
		goto __fail;
	}
	sz = st.st_size;
	count = snd_ctl_elem_info_get_count(info);
	if (sz != count || sz > sizeof(dst->value.bytes)) {
		uc_error("invalid parameter size %d!", sz);
		err = -EINVAL;
		goto __fail;
	}
	res = malloc(sz);
	if (res == NULL) {
		err = -ENOMEM;
		goto __fail;
	}
	sz_read = read(fd, res, sz);
	if (sz_read < 0 || (size_t)sz_read != sz) {
		err = -errno;
		goto __fail_read;
	}
	for (idx = 0; idx < sz; idx++)
		snd_ctl_elem_value_set_byte(dst, idx, *(res + idx));
      __fail_read:
	free(res);
      __fail:
	close(fd);
	return err;
}
Exemplo n.º 2
0
static int read_tlv_file(unsigned int **res,
			 const char *filepath)
{
	int err = 0;
	int fd;
	struct stat st;
	size_t sz;
	ssize_t sz_read;
	struct snd_ctl_tlv *tlv;

	fd = open(filepath, O_RDONLY);
	if (fd < 0) {
		err = -errno;
		return err;
	}
	if (fstat(fd, &st) == -1) {
		err = -errno;
		goto __fail;
	}
	sz = st.st_size;
	if (sz > 16 * 1024 * 1024 || sz < 8 || sz % 4) {
		uc_error("File size should be less than 16 MB "
			 "and multiple of 4");
		err = -EINVAL;
		goto __fail;
	}
	*res = malloc(sz);
	if (res == NULL) {
		err = -ENOMEM;
		goto __fail;
	}
	sz_read = read(fd, *res, sz);
	if (sz_read < 0 || (size_t)sz_read != sz) {
		err = -EIO;
		free(*res);
		*res = NULL;
	}
	/* Check if the tlv file specifies valid size. */
	tlv = (struct snd_ctl_tlv *)(*res);
	if (tlv->length + 2 * sizeof(unsigned int) != sz) {
		uc_error("Invalid tlv size: %d", tlv->length);
		err = -EINVAL;
		free(*res);
		*res = NULL;
	}

__fail:
	close(fd);
	return err;
}
Exemplo n.º 3
0
/*
 * Parse safe ID
 */
int parse_is_name_safe(char *name)
{
	if (strchr(name, '.')) {
		uc_error("char '.' now allowed in '%s'", name);
		return 0;
	}
	return 1;
}
Exemplo n.º 4
0
static int execute_cset(snd_ctl_t *ctl, const char *cset)
{
	const char *pos;
	int err;
	snd_ctl_elem_id_t *id;
	snd_ctl_elem_value_t *value;
	snd_ctl_elem_info_t *info;

	snd_ctl_elem_id_malloc(&id);
	snd_ctl_elem_value_malloc(&value);
	snd_ctl_elem_info_malloc(&info);

	err = __snd_ctl_ascii_elem_id_parse(id, cset, &pos);
	if (err < 0)
		goto __fail;
	while (*pos && isspace(*pos))
		pos++;
	if (!*pos) {
		uc_error("undefined value for cset >%s<", cset);
		err = -EINVAL;
		goto __fail;
	}
	snd_ctl_elem_value_set_id(value, id);
	snd_ctl_elem_info_set_id(info, id);
	err = snd_ctl_elem_read(ctl, value);
	if (err < 0)
		goto __fail;
	err = snd_ctl_elem_info(ctl, info);
	if (err < 0)
		goto __fail;
	err = snd_ctl_ascii_value_parse(ctl, value, info, pos);
	if (err < 0)
		goto __fail;
	err = snd_ctl_elem_write(ctl, value);
	if (err < 0)
		goto __fail;
	err = 0;
      __fail:
	if (id != NULL)
		free(id);
	if (value != NULL)
		free(value);
	if (info != NULL)
		free(info);

	return err;
}
Exemplo n.º 5
0
/*
 * Parse transition
 */
static int parse_transition(snd_use_case_mgr_t *uc_mgr,
			    struct list_head *tlist,
			    snd_config_t *cfg)
{
	struct transition_sequence *tseq;
	const char *id;
	snd_config_iterator_t i, next;
	snd_config_t *n;
	int err;

	if (snd_config_get_id(cfg, &id) < 0)
		return -EINVAL;

	if (snd_config_get_type(cfg) != SND_CONFIG_TYPE_COMPOUND) {
		uc_error("compound type expected for %s", id);
		return -EINVAL;
	}

	snd_config_for_each(i, next, cfg) {
		n = snd_config_iterator_entry(i);

		if (snd_config_get_id(n, &id) < 0)
			return -EINVAL;

		tseq = calloc(1, sizeof(*tseq));
		if (tseq == NULL)
			return -ENOMEM;
		INIT_LIST_HEAD(&tseq->transition_list);

		tseq->name = strdup(id);
		if (tseq->name == NULL) {
			free(tseq);
			return -ENOMEM;
		}
	
		err = parse_sequence(uc_mgr, &tseq->transition_list, n);
		if (err < 0) {
			uc_mgr_free_transition_element(tseq);
			return err;
		}

		list_add(&tseq->list, tlist);
	}
Exemplo n.º 6
0
/**
 * \brief Execute the sequence
 * \param uc_mgr Use case manager
 * \param seq Sequence
 * \return zero on success, otherwise a negative error code
 */
static int execute_sequence(snd_use_case_mgr_t *uc_mgr,
			    struct list_head *seq,
			    struct list_head *value_list1,
			    struct list_head *value_list2,
			    struct list_head *value_list3)
{
	struct list_head *pos;
	struct sequence_element *s;
	char *cdev = NULL;
	snd_ctl_t *ctl = NULL;
	int err = 0;

	list_for_each(pos, seq) {
		s = list_entry(pos, struct sequence_element, list);
		switch (s->type) {
		case SEQUENCE_ELEMENT_TYPE_CDEV:
			cdev = strdup(s->data.cdev);
			if (cdev == NULL)
				goto __fail_nomem;
			break;
		case SEQUENCE_ELEMENT_TYPE_CSET:
			if (cdev == NULL) {
				const char *cdev1 = NULL, *cdev2 = NULL;
				err = get_value3(&cdev1, "PlaybackCTL",
						 value_list1,
						 value_list2,
						 value_list3);
				if (err < 0 && err != ENOENT) {
					uc_error("cdev is not defined!");
					return err;
				}
				err = get_value3(&cdev1, "CaptureCTL",
						 value_list1,
						 value_list2,
						 value_list3);
				if (err < 0 && err != ENOENT) {
					free((char *)cdev1);
					uc_error("cdev is not defined!");
					return err;
				}
				if (cdev1 == NULL || cdev2 == NULL ||
                                    strcmp(cdev1, cdev2) == 0) {
					cdev = (char *)cdev1;
					free((char *)cdev2);
				} else {
					free((char *)cdev1);
					free((char *)cdev2);
				}
			}
			if (ctl == NULL) {
				err = open_ctl(uc_mgr, &ctl, cdev);
				if (err < 0) {
					uc_error("unable to open ctl device '%s'", cdev);
					goto __fail;
				}
			}
			err = execute_cset(ctl, s->data.cset);
			if (err < 0) {
				uc_error("unable to execute cset '%s'\n", s->data.cset);
				goto __fail;
			}
			break;
		case SEQUENCE_ELEMENT_TYPE_SLEEP:
			usleep(s->data.sleep);
			break;
		case SEQUENCE_ELEMENT_TYPE_EXEC:
			err = system(s->data.exec);
			if (err < 0)
				goto __fail;
			break;
		default:
			uc_error("unknown sequence command %i", s->type);
			break;
		}
	}
Exemplo n.º 7
0
static int execute_cset(snd_ctl_t *ctl, const char *cset, unsigned int type)
{
	const char *pos;
	int err;
	snd_ctl_elem_id_t *id;
	snd_ctl_elem_value_t *value;
	snd_ctl_elem_info_t *info;
	unsigned int *res = NULL;

	snd_ctl_elem_id_malloc(&id);
	snd_ctl_elem_value_malloc(&value);
	snd_ctl_elem_info_malloc(&info);

	err = __snd_ctl_ascii_elem_id_parse(id, cset, &pos);
	if (err < 0)
		goto __fail;
	while (*pos && isspace(*pos))
		pos++;
	if (!*pos) {
		uc_error("undefined value for cset >%s<", cset);
		err = -EINVAL;
		goto __fail;
	}
	snd_ctl_elem_info_set_id(info, id);
	err = snd_ctl_elem_info(ctl, info);
	if (err < 0)
		goto __fail;
	if (type == SEQUENCE_ELEMENT_TYPE_CSET_TLV) {
		if (!snd_ctl_elem_info_is_tlv_writable(info)) {
			err = -EINVAL;
			goto __fail;
		}
		err = read_tlv_file(&res, pos);
		if (err < 0)
			goto __fail;
		err = snd_ctl_elem_tlv_write(ctl, id, res);
		if (err < 0)
			goto __fail;
	} else {
		snd_ctl_elem_value_set_id(value, id);
		err = snd_ctl_elem_read(ctl, value);
		if (err < 0)
			goto __fail;
		if (type == SEQUENCE_ELEMENT_TYPE_CSET_BIN_FILE)
			err = binary_file_parse(value, info, pos);
		else
			err = snd_ctl_ascii_value_parse(ctl, value, info, pos);
		if (err < 0)
			goto __fail;
		err = snd_ctl_elem_write(ctl, value);
		if (err < 0)
			goto __fail;
	}
	err = 0;
      __fail:
	if (id != NULL)
		free(id);
	if (value != NULL)
		free(value);
	if (info != NULL)
		free(info);
	if (res != NULL)
		free(res);

	return err;
}