Exemple #1
0
static int media_decode(struct sdp_media **mp, struct sdp_session *sess,
			bool offer, const struct pl *pl)
{
	struct pl name, port, proto, fmtv, fmt;
	struct sdp_media *m;
	int err;

	if (re_regex(pl->p, pl->l, "[a-z]+ [^ ]+ [^ ]+[^]*",
		     &name, &port, &proto, &fmtv))
		return EBADMSG;

	m = list_ledata(*mp ? (*mp)->le.next : sess->medial.head);
	if (!m) {
		if (!offer)
			return EPROTO;

		m = sdp_media_find(sess, &name, &proto);
		if (!m) {
			err = sdp_media_radd(&m, sess, &name, &proto);
			if (err)
				return err;
		}
		else {
			list_unlink(&m->le);
			list_append(&sess->medial, &m->le, m);
		}
	}
	else {
		if (pl_strcmp(&name, m->name))
			return offer ? ENOTSUP : EPROTO;

		if (pl_strcmp(&proto, m->proto))
			return ENOTSUP;
	}

	while (!re_regex(fmtv.p, fmtv.l, " [^ ]+", &fmt)) {

		pl_advance(&fmtv, fmt.p + fmt.l - fmtv.p);

		err = sdp_format_radd(m, &fmt);
		if (err)
			return err;
	}

	m->raddr = sess->raddr;
	sa_set_port(&m->raddr, pl_u32(&port));

	m->rdir = sess->rdir;

	*mp = m;

	return 0;
}
Exemple #2
0
static int print_handler(const char *p, size_t size, void *arg)
{
	struct pl *pl = arg;

	if (size > pl->l)
		return ENOMEM;

	memcpy((void *)pl->p, p, size);

	pl_advance(pl, size);

	return 0;
}
Exemple #3
0
/** Compare two SDP messages line-by-line (exclude owner) */
static bool sdp_cmp(struct mbuf *mb, const char *msg)
{
	struct pl pl;

	if (!mb || !msg)
		return false;

	pl.p = (char *)mb->buf;
	pl.l = mb->end;

	while (pl.l && strlen(msg)) {
		struct pl n1, v1, n2, v2;

		if (re_regex(pl.p, pl.l,
			     "[^=]1=[^\r\n]+", &n1, &v1))
			return false;

		if (re_regex(msg, strlen(msg),
			     "[^=]1=[^\r\n]+", &n2, &v2))
			return false;

		pl_advance(&pl, 2 + v1.l + 2);
		msg += (2 + v2.l + 2);

		if (0 != pl_cmp(&n1, &n2)) {
			DEBUG_WARNING("name mismatch: %r=%r\n", &n1, &v1);
			return false;
		}

		/* ignore owner */
		if (n1.p[0] == 'o')
			continue;

		if (0 != pl_cmp(&v1, &v2)) {
			DEBUG_WARNING("value mismatch: %r=%r\n",
				      &n1, &v1);
			return false;
		}
	}

	if (pl.l) {
		DEBUG_WARNING("%u bytes junk at end: %r\n", pl.l, &pl);
	}

	if (strlen(msg)) {
		DEBUG_WARNING("%u bytes junk at end: %s\n", strlen(msg), msg);
	}

	return !pl.l && !strlen(msg);
}
Exemple #4
0
/**
 * Parse a config file, calling handler for each line
 *
 * @param filename Config file
 * @param ch       Line handler
 * @param arg      Handler argument
 *
 * @return 0 if success, otherwise errorcode
 */
int conf_parse(const char *filename, confline_h *ch, void *arg)
{
	struct pl pl, val;
	struct mbuf *mb;
	int err = 0, fd = open(filename, O_RDONLY);
	if (fd < 0)
		return errno;

	mb = mbuf_alloc(1024);
	if (!mb) {
		err = ENOMEM;
		goto out;
	}

	for (;;) {
		uint8_t buf[1024];

		const ssize_t n = read(fd, (void *)buf, sizeof(buf));
		if (n < 0) {
			err = errno;
			break;
		}
		else if (n == 0)
			break;

		err |= mbuf_write_mem(mb, buf, n);
	}

	pl.p = (const char *)mb->buf;
	pl.l = mb->end;

	while (pl.p < ((const char *)mb->buf + mb->end) && !err) {
		const char *lb = pl_strchr(&pl, '\n');

		val.p = pl.p;
		val.l = lb ? (uint32_t)(lb - pl.p) : pl.l;
		pl_advance(&pl, val.l + 1);

		if (!val.l || val.p[0] == '#')
			continue;

		err = ch(&val, arg);
	}

 out:
	mem_deref(mb);
	(void)close(fd);

	return err;
}
Exemple #5
0
static void decode_param(const struct pl *name, const struct pl *val,
			 void *arg)
{
	struct aucodec_st *st = arg;
	int err;

	if (0 == pl_strcasecmp(name, "bitrate")) {
		st->bitrate = pl_u32(val) * 1000;
	}
	else if (0 == pl_strcasecmp(name, "frame-size")) {
		st->frame_size = pl_u32(val);

		if (st->frame_size & 0x1) {
			DEBUG_WARNING("frame-size is NOT even: %u\n",
				      st->frame_size);
		}
	}
	else if (0 == pl_strcasecmp(name, "low-overhead")) {
		struct pl fs, bpfv;
		uint32_t i;

		st->low_overhead = true;

		err = re_regex(val->p, val->l, "[0-9]+/[0-9,]+", &fs, &bpfv);
		if (err)
			return;

		st->frame_size = pl_u32(&fs);

		for (i=0; i<ARRAY_SIZE(st->bpfv) && bpfv.l > 0; i++) {
			struct pl bpf, co;

			co.l = 0;
			if (re_regex(bpfv.p, bpfv.l, "[0-9]+[,]*", &bpf, &co))
				break;

			pl_advance(&bpfv, bpf.l + co.l);

			st->bpfv[i] = pl_u32(&bpf);
		}
		st->bpfn = i;
	}
	else {
		DEBUG_NOTICE("unknown param: %r = %r\n", name, val);
	}
}
static int cand_decode(struct icem *icem, const char *val)
{
	struct pl foundation, compid, transp, prio, addr, port, cand_type;
	struct pl extra = pl_null;
	struct sa caddr, rel_addr;
	char type[8];
	uint8_t cid;
	int err;

	sa_init(&rel_addr, AF_INET);

	err = re_regex(val, strlen(val),
		       "[^ ]+ [0-9]+ [^ ]+ [0-9]+ [^ ]+ [0-9]+ typ [a-z]+[^]*",
		       &foundation, &compid, &transp, &prio,
		       &addr, &port, &cand_type, &extra);
	if (err)
		return err;

	if (ICE_TRANSP_NONE == transp_resolve(&transp)) {
		DEBUG_NOTICE("<%s> ignoring candidate with"
			     " unknown transport=%r (%r:%r)\n",
			     icem->name, &transp, &cand_type, &addr);
		return 0;
	}

	if (pl_isset(&extra)) {

		struct pl name, value;

		/* Loop through " SP attr SP value" pairs */
		while (!re_regex(extra.p, extra.l, " [^ ]+ [^ ]+",
				 &name, &value)) {

			pl_advance(&extra, value.p + value.l - extra.p);

			if (0 == pl_strcasecmp(&name, rel_addr_str)) {
				err = sa_set(&rel_addr, &value,
					     sa_port(&rel_addr));
				if (err)
					break;
			}
			else if (0 == pl_strcasecmp(&name, rel_port_str)) {
				sa_set_port(&rel_addr, pl_u32(&value));
			}
		}
	}

	err = sa_set(&caddr, &addr, pl_u32(&port));
	if (err)
		return err;

	cid = pl_u32(&compid);

	/* add only if not exist */
	if (icem_cand_find(&icem->rcandl, cid, &caddr))
		return 0;

	(void)pl_strcpy(&cand_type, type, sizeof(type));

	return icem_rcand_add(icem, ice_cand_name2type(type), cid,
			      pl_u32(&prio), &caddr, &rel_addr, &foundation);
}