예제 #1
0
파일: msg.c 프로젝트: Issic47/libre
/**
 * Decode a SIP message
 *
 * @param msgp Pointer to allocated SIP Message
 * @param mb   Buffer containing SIP Message
 *
 * @return 0 if success, otherwise errorcode
 */
int sip_msg_decode(struct sip_msg **msgp, struct mbuf *mb)
{
	struct pl x, y, z, e, name;
	const char *p, *v, *cv;
	struct sip_msg *msg;
	bool comsep, quote;
	enum sip_hdrid id = SIP_HDR_NONE;
	uint32_t ws, lf;
	size_t l;
	int err;

	if (!msgp || !mb)
		return EINVAL;

	p = (const char *)mbuf_buf(mb);
	l = mbuf_get_left(mb);

	if (re_regex(p, l, "[^ \t\r\n]+ [^ \t\r\n]+ [^\r\n]*[\r]*[\n]1",
		     &x, &y, &z, NULL, &e) || x.p != (char *)mbuf_buf(mb))
		return (l > STARTLINE_MAX) ? EBADMSG : ENODATA;

	msg = mem_zalloc(sizeof(*msg), destructor);
	if (!msg)
		return ENOMEM;

	err = hash_alloc(&msg->hdrht, HDR_HASH_SIZE);
	if (err)
		goto out;

	msg->tag = rand_u64();
	msg->mb  = mem_ref(mb);
	msg->req = (0 == pl_strcmp(&z, "SIP/2.0"));

	if (msg->req) {

		msg->met = x;
		msg->ruri = y;
		msg->ver = z;

		if (uri_decode(&msg->uri, &y)) {
			err = EBADMSG;
			goto out;
		}
	}
	else {
		msg->ver    = x;
		msg->scode  = pl_u32(&y);
		msg->reason = z;

		if (!msg->scode) {
			err = EBADMSG;
			goto out;
		}
	}

	l -= e.p + e.l - p;
	p = e.p + e.l;

	name.p = v = cv = NULL;
	name.l = ws = lf = 0;
	comsep = false;
	quote = false;

	for (; l > 0; p++, l--) {

		switch (*p) {

		case ' ':
		case '\t':
			lf = 0; /* folding */
			++ws;
			break;

		case '\r':
			++ws;
			break;

		case '\n':
			++ws;

			if (!lf++)
				break;

			++p; --l; /* eoh */

			/*@fallthrough@*/

		default:
			if (lf || (*p == ',' && comsep && !quote)) {

				if (!name.l) {
					err = EBADMSG;
					goto out;
				}

				err = hdr_add(msg, &name, id, cv ? cv : p,
					      cv ? p - cv - ws : 0,
					      true, cv == v && lf);
				if (err)
					goto out;

				if (!lf) { /* comma separated */
					cv = NULL;
					break;
				}

				if (cv != v) {
					err = hdr_add(msg, &name, id,
						      v ? v : p,
						      v ? p - v - ws : 0,
						      false, true);
					if (err)
						goto out;
				}

				if (lf > 1) { /* eoh */
					err = 0;
					goto out;
				}

				comsep = false;
				name.p = NULL;
				cv = v = NULL;
				lf = 0;
			}

			if (!name.p) {
				name.p = p;
				name.l = 0;
				ws = 0;
			}

			if (!name.l) {
				if (*p != ':') {
					ws = 0;
					break;
				}

				name.l = MAX((int)(p - name.p - ws), 0);
				if (!name.l) {
					err = EBADMSG;
					goto out;
				}

				id = hdr_hash(&name);
				comsep = hdr_comma_separated(id);
				break;
			}

			if (!cv) {
				quote = false;
				cv = p;
			}

			if (!v) {
				v = p;
			}

			if (*p == '"')
				quote = !quote;

			ws = 0;
			break;
		}
	}

	err = ENODATA;

 out:
	if (err)
		mem_deref(msg);
	else {
		*msgp = msg;
		mb->pos = mb->end - l;
	}

	return err;
}
예제 #2
0
/**
 * Initialise an empty history list.
 */
static void history_init(size_t entries)
{
	history_ctr = 0;
	history_size = entries;
	history_list = mem_zalloc(history_size * sizeof(struct history_info));
}
예제 #3
0
파일: tls.c 프로젝트: kaija/libre
/**
 * Allocate a new TLS context
 *
 * @param tlsp    Pointer to allocated TLS context
 * @param method  TLS method
 * @param keyfile Optional private key file
 * @param pwd     Optional password
 *
 * @return 0 if success, otherwise errorcode
 */
int tls_alloc(struct tls **tlsp, enum tls_method method, const char *keyfile,
	      const char *pwd)
{
	struct tls *tls;
	int r, err;

	if (!tlsp)
		return EINVAL;

	tls = mem_zalloc(sizeof(*tls), destructor);
	if (!tls)
		return ENOMEM;

	if (!tlsg.up) {
#ifdef SIGPIPE
		/* Set up a SIGPIPE handler */
		(void)signal(SIGPIPE, sigpipe_handle);
#endif

		SSL_library_init();
		tlsg.up = true;
	}

	if (tlsg.tlsc++ == 0) {
		DEBUG_INFO("error strings loaded\n");
		SSL_load_error_strings();
	}

	switch (method) {

	case TLS_METHOD_SSLV23:
		tls->ctx = SSL_CTX_new(SSLv23_method());
		break;

#ifdef USE_OPENSSL_DTLS
	case TLS_METHOD_DTLSV1:
		tls->ctx = SSL_CTX_new(DTLSv1_method());
		break;
#endif

	default:
		DEBUG_WARNING("tls method %d not supported\n", method);
		err = ENOSYS;
		goto out;
	}

	if (!tls->ctx) {
		err = ENOMEM;
		goto out;
	}

#if (OPENSSL_VERSION_NUMBER < 0x00905100L)
	SSL_CTX_set_verify_depth(tls->ctx, 1);
#endif

	if (method == TLS_METHOD_DTLSV1) {
		SSL_CTX_set_read_ahead(tls->ctx, 1);
	}

	/* Load our keys and certificates */
	if (keyfile) {
		if (pwd) {
			err = str_dup(&tls->pass, pwd);
			if (err)
				goto out;

			SSL_CTX_set_default_passwd_cb(tls->ctx, password_cb);
			SSL_CTX_set_default_passwd_cb_userdata(tls->ctx, tls);
		}

		r = SSL_CTX_use_certificate_chain_file(tls->ctx, keyfile);
		if (r <= 0) {
			DEBUG_WARNING("Can't read certificate file: %s (%d)\n",
				      keyfile, r);
			err = EINVAL;
			goto out;
		}

		r = SSL_CTX_use_PrivateKey_file(tls->ctx, keyfile,
						SSL_FILETYPE_PEM);
		if (r <= 0) {
			DEBUG_WARNING("Can't read key file: %s (%d)\n",
				      keyfile, r);
			err = EINVAL;
			goto out;
		}
	}

	err = 0;
 out:
	if (err)
		mem_deref(tls);
	else
		*tlsp = tls;

	return err;
}
예제 #4
0
static int query(struct dns_query **qp, struct dnsc *dnsc, uint8_t opcode,
		 const char *name, uint16_t type, uint16_t dnsclass,
		 const struct dnsrr *ans_rr, int proto,
		 const struct sa *srvv, const uint32_t *srvc,
		 bool aa, bool rd, dns_query_h *qh, void *arg)
{
	struct dns_query *q = NULL;
	struct dnshdr hdr;
	int err = 0;
	uint32_t i;

	if (!dnsc || !name || !srvv || !srvc || !(*srvc))
		return EINVAL;

	if (DNS_QTYPE_AXFR == type)
		proto = IPPROTO_TCP;

	q = mem_zalloc(sizeof(*q), query_destructor);
	if (!q)
		goto nmerr;

	hash_append(dnsc->ht_query, hash_joaat_str_ci(name), &q->le, q);
	tmr_init(&q->tmr);
	mbuf_init(&q->mb);

	for (i=0; i<ARRAY_SIZE(q->rrlv); i++)
		list_init(&q->rrlv[i]);

	err = str_dup(&q->name, name);
	if (err)
		goto error;

	q->srvv = srvv;
	q->srvc = srvc;
	q->id   = rand_u16();
	q->type = type;
	q->opcode = opcode;
	q->dnsclass = dnsclass;
	q->dnsc = dnsc;

	memset(&hdr, 0, sizeof(hdr));

	hdr.id = q->id;
	hdr.opcode = q->opcode;
	hdr.aa = aa;
	hdr.rd = rd;
	hdr.nq = 1;
	hdr.nans = ans_rr ? 1 : 0;

	if (proto == IPPROTO_TCP)
		q->mb.pos += 2;

	err = dns_hdr_encode(&q->mb, &hdr);
	if (err)
		goto error;

	err = dns_dname_encode(&q->mb, name, NULL, 0, false);
	if (err)
		goto error;

	err |= mbuf_write_u16(&q->mb, htons(type));
	err |= mbuf_write_u16(&q->mb, htons(dnsclass));
	if (err)
		goto error;

	if (ans_rr) {
		err = dns_rr_encode(&q->mb, ans_rr, 0, NULL, 0);
		if (err)
			goto error;
	}

	q->qh  = qh;
	q->arg = arg;

	switch (proto) {

	case IPPROTO_TCP:
		q->mb.pos = 0;
		(void)mbuf_write_u16(&q->mb, htons(q->mb.end - 2));

		err = send_tcp(q);
		if (err)
			goto error;

		tmr_start(&q->tmr, 60 * 1000, tcp_timeout_handler, q);
		break;

	case IPPROTO_UDP:
		err = send_udp(q);
		if (err)
			goto error;

		tmr_start(&q->tmr, 500, udp_timeout_handler, q);
		break;

	default:
		err = EPROTONOSUPPORT;
		goto error;
	}

	if (qp) {
		q->qp = qp;
		*qp = q;
	}

	return 0;

 nmerr:
	err = ENOMEM;
 error:
	mem_deref(q);

	return err;
}
예제 #5
0
파일: encode.c 프로젝트: mralexgray/baresip
int encode_update(struct videnc_state **vesp, const struct vidcodec *vc,
		  struct videnc_param *prm, const char *fmtp)
{
	struct videnc_state *st;
	int err = 0;

	if (!vesp || !vc || !prm)
		return EINVAL;

	if (*vesp)
		return 0;

	st = mem_zalloc(sizeof(*st), destructor);
	if (!st)
		return ENOMEM;

	st->encprm = *prm;

	st->codec_id = avcodec_resolve_codecid(vc->name);
	if (st->codec_id == CODEC_ID_NONE) {
		err = EINVAL;
		goto out;
	}

	st->mb  = mbuf_alloc(FF_MIN_BUFFER_SIZE * 20);
	st->mb_frag = mbuf_alloc(1024);
	if (!st->mb || !st->mb_frag) {
		err = ENOMEM;
		goto out;
	}

	st->sz_max = st->mb->size;

	if (st->codec_id == CODEC_ID_H264) {
#ifndef USE_X264
		err = init_encoder(st);
#endif
	}
	else
		err = init_encoder(st);
	if (err) {
		DEBUG_WARNING("%s: could not init encoder\n", vc->name);
		goto out;
	}

	if (str_isset(fmtp)) {
		struct pl sdp_fmtp;

		pl_set_str(&sdp_fmtp, fmtp);

		fmt_param_apply(&sdp_fmtp, param_handler, st);
	}

	re_printf("video encoder %s: %d fps, %d bit/s, pktsize=%u\n",
		  vc->name, prm->fps, prm->bitrate, prm->pktsize);

 out:
	if (err)
		mem_deref(st);
	else
		*vesp = st;

	return err;
}
예제 #6
0
int setup_tests(void **state) {
	z_info = mem_zalloc(sizeof(struct angband_constants));
	z_info->max_sight = 20;
	*state = init_parse_monster();
	return !*state;
}
예제 #7
0
파일: audio.c 프로젝트: quentusrex/baresip
static int start_player(struct aurx *rx, struct audio *a)
{
	const struct aucodec *ac = rx->ac;
	uint32_t srate_dsp = get_srate(ac);
	uint32_t channels_dsp;
	bool resamp = false;
	int err;

	if (!ac)
		return 0;

	channels_dsp = ac->ch;

	if (a->cfg.srate_play && a->cfg.srate_play != srate_dsp) {
		resamp = true;
		srate_dsp = a->cfg.srate_play;
	}
	if (a->cfg.channels_play && a->cfg.channels_play != channels_dsp) {
		resamp = true;
		channels_dsp = a->cfg.channels_play;
	}

	/* Optional resampler, if configured */
	if (resamp && !rx->sampv_rs) {

		info("audio: enable auplay resampler:"
		     " %uHz/%uch --> %uHz/%uch\n",
		     get_srate(ac), ac->ch, srate_dsp, channels_dsp);

		rx->sampv_rs = mem_zalloc(AUDIO_SAMPSZ * 2, NULL);
		if (!rx->sampv_rs)
			return ENOMEM;

		err = auresamp_setup(&rx->resamp,
				     get_srate(ac), ac->ch,
				     srate_dsp, channels_dsp);
		if (err) {
			warning("audio: could not setup auplay resampler"
				" (%m)\n", err);
			return err;
		}
	}

	/* Start Audio Player */
	if (!rx->auplay && auplay_find(NULL)) {

		struct auplay_prm prm;

		prm.srate      = srate_dsp;
		prm.ch         = channels_dsp;
		prm.ptime      = rx->ptime;

		if (!rx->aubuf) {
			size_t psize;

			psize = 2 * calc_nsamp(prm.srate, prm.ch, prm.ptime);

			err = aubuf_alloc(&rx->aubuf, psize * 1, psize * 8);
			if (err)
				return err;
		}

		err = auplay_alloc(&rx->auplay, a->cfg.play_mod,
				   &prm, rx->device,
				   auplay_write_handler, rx);
		if (err) {
			warning("audio: start_player failed (%s.%s): %m\n",
				a->cfg.play_mod, rx->device, err);
			return err;
		}
	}

	return 0;
}
예제 #8
0
파일: ui-object.c 프로젝트: angband/angband
/**
 * Let the user select an object, save its address
 *
 * Return true only if an acceptable item was chosen by the user.
 *
 * The user is allowed to choose acceptable items from the equipment,
 * inventory, quiver, or floor, respectively, if the proper flag was given,
 * and there are any acceptable items in that location.
 *
 * The equipment, inventory or quiver are displayed (even if no acceptable
 * items are in that location) if the proper flag was given.
 *
 * If there are no acceptable items available anywhere, and "str" is
 * not NULL, then it will be used as the text of a warning message
 * before the function returns.
 *
 * If a legal item is selected , we save it in "choice" and return true.
 *
 * If no item is available, we do nothing to "choice", and we display a
 * warning message, using "str" if available, and return false.
 *
 * If no item is selected, we do nothing to "choice", and return false.
 *
 * Global "player->upkeep->command_wrk" is used to choose between
 * equip/inven/quiver/floor listings.  It is equal to USE_INVEN or USE_EQUIP or
 * USE_QUIVER or USE_FLOOR, except when this function is first called, when it
 * is equal to zero, which will cause it to be set to USE_INVEN.
 *
 * We always erase the prompt when we are done, leaving a blank line,
 * or a warning message, if appropriate, if no items are available.
 *
 * Note that only "acceptable" floor objects get indexes, so between two
 * commands, the indexes of floor objects may change.  XXX XXX XXX
 */
bool textui_get_item(struct object **choice, const char *pmt, const char *str,
					 cmd_code cmd, item_tester tester, int mode)
{
	bool use_inven = ((mode & USE_INVEN) ? true : false);
	bool use_equip = ((mode & USE_EQUIP) ? true : false);
	bool use_quiver = ((mode & USE_QUIVER) ? true : false);
	bool use_floor = ((mode & USE_FLOOR) ? true : false);
	bool quiver_tags = ((mode & QUIVER_TAGS) ? true : false);

	bool allow_inven = false;
	bool allow_equip = false;
	bool allow_quiver = false;
	bool allow_floor = false;

	bool toggle = false;

	int floor_max = z_info->floor_size;
	int floor_num;

	floor_list = mem_zalloc(floor_max * sizeof(*floor_list));
	olist_mode = 0;
	item_mode = mode;
	item_cmd = cmd;
	tester_m = tester;
	prompt = pmt;
	allow_all = str ? false : true;

	/* Object list display modes */
	if (mode & SHOW_FAIL)
		olist_mode |= OLIST_FAIL;
	else
		olist_mode |= OLIST_WEIGHT;

	if (mode & SHOW_PRICES)
		olist_mode |= OLIST_PRICE;

	if (mode & SHOW_EMPTY)
		olist_mode |= OLIST_SEMPTY;

	if (mode & SHOW_QUIVER)
		olist_mode |= OLIST_QUIVER;

	if (mode & SHOW_RECHARGE)
		olist_mode |= OLIST_RECHARGE;

	/* Paranoia XXX XXX XXX */
	event_signal(EVENT_MESSAGE_FLUSH);

	/* Full inventory */
	i1 = 0;
	i2 = z_info->pack_size - 1;

	/* Forbid inventory */
	if (!use_inven) i2 = -1;

	/* Restrict inventory indexes */
	while ((i1 <= i2) && (!object_test(tester, player->upkeep->inven[i1])))
		i1++;
	while ((i1 <= i2) && (!object_test(tester, player->upkeep->inven[i2])))
		i2--;

	/* Accept inventory */
	if ((i1 <= i2) || allow_all)
		allow_inven = true;
	else if (item_mode & USE_INVEN)
		item_mode -= USE_INVEN;

	/* Full equipment */
	e1 = 0;
	e2 = player->body.count - 1;

	/* Forbid equipment */
	if (!use_equip) e2 = -1;

	/* Restrict equipment indexes unless starting with no command */
	if ((cmd != CMD_NULL) || (tester != NULL)) {
		while ((e1 <= e2) && (!object_test(tester, slot_object(player, e1))))
			e1++;
		while ((e1 <= e2) && (!object_test(tester, slot_object(player, e2))))
			e2--;
	}

	/* Accept equipment */
	if ((e1 <= e2) || allow_all)
		allow_equip = true;
	else if (item_mode & USE_EQUIP)
		item_mode -= USE_EQUIP;

	/* Restrict quiver indexes */
	q1 = 0;
	q2 = z_info->quiver_size - 1;

	/* Forbid quiver */
	if (!use_quiver) q2 = -1;

	/* Restrict quiver indexes */
	while ((q1 <= q2) && (!object_test(tester, player->upkeep->quiver[q1])))
		q1++;
	while ((q1 <= q2) && (!object_test(tester, player->upkeep->quiver[q2])))
		q2--;

	/* Accept quiver */
	if ((q1 <= q2) || allow_all)
		allow_quiver = true;
	else if (item_mode & USE_QUIVER)
		item_mode -= USE_QUIVER;

	/* Scan all non-gold objects in the grid */
	floor_num = scan_floor(floor_list, floor_max,
						   OFLOOR_TEST | OFLOOR_SENSE | OFLOOR_VISIBLE, tester);

	/* Full floor */
	f1 = 0;
	f2 = floor_num - 1;

	/* Forbid floor */
	if (!use_floor) f2 = -1;

	/* Restrict floor indexes */
	while ((f1 <= f2) && (!object_test(tester, floor_list[f1]))) f1++;
	while ((f1 <= f2) && (!object_test(tester, floor_list[f2]))) f2--;

	/* Accept floor */
	if ((f1 <= f2) || allow_all)
		allow_floor = true;
	else if (item_mode & USE_FLOOR)
		item_mode -= USE_FLOOR;

	/* Require at least one legal choice */
	if (allow_inven || allow_equip || allow_quiver || allow_floor) {
		/* Start where requested if possible */
		if ((player->upkeep->command_wrk == USE_EQUIP) && allow_equip)
			player->upkeep->command_wrk = USE_EQUIP;
		else if ((player->upkeep->command_wrk == USE_INVEN) && allow_inven)
			player->upkeep->command_wrk = USE_INVEN;
		else if ((player->upkeep->command_wrk == USE_QUIVER) && allow_quiver)
			player->upkeep->command_wrk = USE_QUIVER;
		else if ((player->upkeep->command_wrk == USE_FLOOR) && allow_floor)
			player->upkeep->command_wrk = USE_FLOOR;

		/* If we are obviously using the quiver then start on quiver */
		else if (quiver_tags && allow_quiver)
			player->upkeep->command_wrk = USE_QUIVER;

		/* Otherwise choose whatever is allowed */
		else if (use_inven && allow_inven)
			player->upkeep->command_wrk = USE_INVEN;
		else if (use_equip && allow_equip)
			player->upkeep->command_wrk = USE_EQUIP;
		else if (use_quiver && allow_quiver)
			player->upkeep->command_wrk = USE_QUIVER;
		else if (use_floor && allow_floor)
			player->upkeep->command_wrk = USE_FLOOR;

		/* If nothing to choose, use (empty) inventory */
		else
			player->upkeep->command_wrk = USE_INVEN;

		while (true) {
			int j;
			int ni = 0;
			int ne = 0;

			/* If inven or equip is on the main screen, and only one of them
			 * is slated for a subwindow, we should show the opposite there */
			for (j = 0; j < ANGBAND_TERM_MAX; j++) {
				/* Unused */
				if (!angband_term[j]) continue;

				/* Count windows displaying inven */
				if (window_flag[j] & (PW_INVEN)) ni++;

				/* Count windows displaying equip */
				if (window_flag[j] & (PW_EQUIP)) ne++;
			}

			/* Are we in the situation where toggling makes sense? */
			if ((ni && !ne) || (!ni && ne)) {
				if (player->upkeep->command_wrk == USE_EQUIP) {
					if ((ne && !toggle) || (ni && toggle)) {
						/* Main screen is equipment, so is subwindow */
						toggle_inven_equip();
						toggle = !toggle;
					}
				} else if (player->upkeep->command_wrk == USE_INVEN) {
					if ((ni && !toggle) || (ne && toggle)) {
						/* Main screen is inventory, so is subwindow */
						toggle_inven_equip();
						toggle = !toggle;
					}
				} else {
					/* Quiver or floor, go back to the original */
					if (toggle) {
						toggle_inven_equip();
						toggle = !toggle;
					}
				}
			}

			/* Redraw */
			player->upkeep->redraw |= (PR_INVEN | PR_EQUIP);

			/* Redraw windows */
			redraw_stuff(player);

			/* Save screen */
			screen_save();

			/* Build object list */
			wipe_obj_list();
			if (player->upkeep->command_wrk == USE_INVEN)
				build_obj_list(i2, player->upkeep->inven, tester_m, olist_mode);
			else if (player->upkeep->command_wrk == USE_EQUIP)
				build_obj_list(e2, NULL, tester_m, olist_mode);
			else if (player->upkeep->command_wrk == USE_QUIVER)
				build_obj_list(q2, player->upkeep->quiver, tester_m,olist_mode);
			else if (player->upkeep->command_wrk == USE_FLOOR)
				build_obj_list(f2, floor_list, tester_m, olist_mode);

			/* Show the prompt */
			menu_header();
			if (pmt) {
				prt(pmt, 0, 0);
				prt(header, 0, strlen(pmt) + 1);
			}

			/* No menu change request */
			newmenu = false;

			/* Get an item choice */
			*choice = item_menu(cmd, MAX(pmt ? strlen(pmt) : 0, 15), mode);

			/* Fix the screen */
			screen_load();

			/* Update */
			player->upkeep->redraw |= (PR_INVEN | PR_EQUIP);
			redraw_stuff(player);

			/* Clear the prompt line */
			prt("", 0, 0);

			/* We have a selection, or are backing out */
			if (*choice || !newmenu) {
				if (toggle) toggle_inven_equip();
				break;
			}
		}
	} else {
		/* Warning if needed */
		if (str) msg("%s", str);
		*choice = NULL;
	}

	/* Clean up */
	player->upkeep->command_wrk = 0;
	mem_free(floor_list);

	/* Result */
	return (*choice != NULL) ? true : false;
}
예제 #9
0
/**
 * Allocate a new NAT Mapping Behaviour Discovery session
 *
 * @param nmp       Pointer to allocated NAT Mapping object
 * @param laddr     Local IP address
 * @param srv       STUN Server IP address and port
 * @param proto     Transport protocol
 * @param conf      STUN configuration (Optional)
 * @param mh        Mapping handler
 * @param arg       Handler argument
 *
 * @return 0 if success, errorcode if failure
 */
int nat_mapping_alloc(struct nat_mapping **nmp, const struct sa *laddr,
		      const struct sa *srv, int proto,
		      const struct stun_conf *conf,
		      nat_mapping_h *mh, void *arg)
{
	struct nat_mapping *nm;
	int i, err;

	if (!nmp || !laddr || !srv || !mh)
		return EINVAL;

	nm = mem_zalloc(sizeof(*nm), mapping_destructor);
	if (!nm)
		return ENOMEM;

	err = stun_alloc(&nm->stun, conf, NULL, NULL);
	if (err)
		goto out;

	nm->proto = proto;
	sa_cpy(&nm->laddr, laddr);

	switch (proto) {

	case IPPROTO_UDP:
		err = udp_listen(&nm->us, &nm->laddr, udp_recv_handler, nm);
		if (err)
			goto out;
		err = udp_local_get(nm->us, &nm->laddr);
		if (err)
			goto out;
		break;

	case IPPROTO_TCP:

		/* Allocate and bind 3 TCP Sockets */
		for (i=0; i<3; i++) {
			err = tcp_conn_alloc(&nm->tcv[i], srv,
					     tcp_estab_handler,
					     tcp_recv_handler,
					     tcp_close_handler, nm);
			if (err)
				goto out;

			err = tcp_conn_bind(nm->tcv[i], &nm->laddr);
			if (err)
				goto out;

			err = tcp_conn_local_get(nm->tcv[i], &nm->laddr);
			if (err)
				goto out;
		}
		break;

	default:
		err = EPROTONOSUPPORT;
		goto out;
	}

	sa_cpy(&nm->srv, srv);
	nm->mh  = mh;
	nm->arg = arg;

	*nmp = nm;

 out:
	if (err)
		mem_deref(nm);
	return err;
}
예제 #10
0
파일: bfcp.c 프로젝트: AmesianX/baresip
int bfcp_alloc(struct bfcp **bfcpp, struct sdp_session *sdp_sess,
	       const char *proto, bool offerer,
	       const struct mnat *mnat, struct mnat_sess *mnat_sess)
{
	struct bfcp *bfcp;
	struct sa laddr;
	enum bfcp_transp transp;
	int err;

	if (!bfcpp || !sdp_sess)
		return EINVAL;

	transp = str2tp(proto);

	bfcp = mem_zalloc(sizeof(*bfcp), destructor);
	if (!bfcp)
		return ENOMEM;

	bfcp->active = offerer;

	sa_init(&laddr, AF_INET);

	err = bfcp_listen(&bfcp->conn, transp, &laddr, uag_tls(),
			  bfcp_msg_handler, bfcp);
	if (err)
		goto out;

	err = sdp_media_add(&bfcp->sdpm, sdp_sess, "application",
			    sa_port(&laddr), bfcp_sdp_transp(transp));
	if (err)
		goto out;

	err = sdp_format_add(NULL, bfcp->sdpm, false, "*", NULL,
			     0, 0, NULL, NULL, NULL, false, NULL);
	if (err)
		goto out;

	err |= sdp_media_set_lattr(bfcp->sdpm, true, "floorctrl", "c-s");
	err |= sdp_media_set_lattr(bfcp->sdpm, true, "setup",
				   bfcp->active ? "active" : "actpass");

	if (bfcp->active) {
		err |= sdp_media_set_lattr(bfcp->sdpm, true,
					   "connection", "new");
	}
	else {
		bfcp->lconfid = 1000 + (rand_u16() & 0xf);
		bfcp->luserid = 1    + (rand_u16() & 0x7);

		err |= sdp_media_set_lattr(bfcp->sdpm, true, "confid",
					   "%u", bfcp->lconfid);
		err |= sdp_media_set_lattr(bfcp->sdpm, true, "userid",
					   "%u", bfcp->luserid);
	}

	if (err)
		goto out;

	if (mnat) {
		info("bfcp: enabled medianat '%s' on UDP socket\n", mnat->id);

		err = mnat->mediah(&bfcp->mnat_st, mnat_sess, IPPROTO_UDP,
				   bfcp_sock(bfcp->conn), NULL, bfcp->sdpm);
		if (err)
			goto out;
	}

	info("bfcp: %s BFCP agent protocol '%s' on port %d\n",
	     bfcp->active ? "Active" : "Passive",
	     proto, sa_port(&laddr));

 out:
	if (err)
		mem_deref(bfcp);
	else
		*bfcpp = bfcp;

	return err;
}
예제 #11
0
파일: ui-object.c 프로젝트: angband/angband
/**
 * Display list items to choose from
 */
struct object *item_menu(cmd_code cmd, int prompt_size, int mode)
{
	menu_iter menu_f = { get_item_tag, get_item_validity, get_item_display,
						 get_item_action, 0 };
	struct menu *m = menu_new(MN_SKIN_OBJECT, &menu_f);
	ui_event evt = { 0 };
	int ex_offset_ctr = 0;
	int row, inscrip;
	struct object *obj = NULL;

	/* Set up the menu */
	menu_setpriv(m, num_obj, items);
	if (player->upkeep->command_wrk == USE_QUIVER)
		m->selections = "0123456789";
	else
		m->selections = lower_case;
	m->switch_keys = "/|-";
	m->flags = (MN_PVT_TAGS | MN_INSCRIP_TAGS);
	m->browse_hook = item_menu_browser;

	/* Get inscriptions */
	m->inscriptions = mem_zalloc(10 * sizeof(char));
	for (inscrip = 0; inscrip < 10; inscrip++) {
		/* Look up the tag */
		if (get_tag(&obj, (char)inscrip + '0', item_cmd,
					item_mode & QUIVER_TAGS)) {
			int i;
			for (i = 0; i < num_obj; i++)
				if (items[i].object == obj)
						break;

			if (i < num_obj)
				m->inscriptions[inscrip] = get_item_tag(m, i);
		}
	}

	/* Set up the item list variables */
	selection = NULL;
	set_obj_names(false);

	if (mode & OLIST_QUIVER && player->upkeep->quiver[0] != NULL)
		max_len = MAX(max_len, 24);

	if (olist_mode & OLIST_WEIGHT) {
		ex_width += 9;
		ex_offset_ctr += 9;
	}
	if (olist_mode & OLIST_PRICE) {
		ex_width += 9;
		ex_offset_ctr += 9;
	}
	if (olist_mode & OLIST_FAIL) {
		ex_width += 10;
		ex_offset_ctr += 10;
	}

	/* Set up the menu region */
	area.page_rows = m->count;
	area.row = 1;
	area.col = MIN(Term->wid - 1 - (int) max_len - ex_width, prompt_size - 2);
	if (area.col <= 3)
		area.col = 0;
	ex_offset = MIN(max_len, (size_t)(Term->wid - 1 - ex_width - area.col));
	while (strlen(header) < max_len + ex_width + ex_offset_ctr) {
		my_strcat(header, " ", sizeof(header));
		if (strlen(header) > sizeof(header) - 2) break;
	}
	area.width = MAX(max_len, strlen(header));

	for (row = area.row; row < area.row + area.page_rows; row++)
		prt("", row, MAX(0, area.col - 1));

	menu_layout(m, &area);

	/* Choose */
	evt = menu_select(m, 0, true);

	/* Clean up */
	mem_free(m->inscriptions);
	mem_free(m);

	/* Deal with menu switch */
	if (evt.type == EVT_SWITCH && !newmenu) {
		bool left = evt.key.code == ARROW_LEFT;

		if (player->upkeep->command_wrk == USE_EQUIP) {
			if (left) {
				if (f1 <= f2) player->upkeep->command_wrk = USE_FLOOR;
				else if (q1 <= q2) player->upkeep->command_wrk = USE_QUIVER;
				else if (i1 <= i2) player->upkeep->command_wrk = USE_INVEN;
			} else {
				if (i1 <= i2) player->upkeep->command_wrk = USE_INVEN;
				else if (q1 <= q2) player->upkeep->command_wrk = USE_QUIVER;
				else if (f1 <= f2) player->upkeep->command_wrk = USE_FLOOR;
			}
		} else if (player->upkeep->command_wrk == USE_INVEN) {
			if (left) {
				if (e1 <= e2) player->upkeep->command_wrk = USE_EQUIP;
				else if (f1 <= f2) player->upkeep->command_wrk = USE_FLOOR;
				else if (q1 <= q2) player->upkeep->command_wrk = USE_QUIVER;
			} else {
				if (q1 <= q2) player->upkeep->command_wrk = USE_QUIVER;
				else if (f1 <= f2) player->upkeep->command_wrk = USE_FLOOR;
				else if (e1 <= e2) player->upkeep->command_wrk = USE_EQUIP;
			}
		} else if (player->upkeep->command_wrk == USE_QUIVER) {
			if (left) {
				if (i1 <= i2) player->upkeep->command_wrk = USE_INVEN;
				else if (e1 <= e2) player->upkeep->command_wrk = USE_EQUIP;
				else if (f1 <= f2) player->upkeep->command_wrk = USE_FLOOR;
			} else {
				if (f1 <= f2) player->upkeep->command_wrk = USE_FLOOR;
				else if (e1 <= e2) player->upkeep->command_wrk = USE_EQUIP;
				else if (i1 <= i2) player->upkeep->command_wrk = USE_INVEN;
			}
		} else if (player->upkeep->command_wrk == USE_FLOOR) {
			if (left) {
				if (q1 <= q2) player->upkeep->command_wrk = USE_QUIVER;
				else if (i1 <= i2) player->upkeep->command_wrk = USE_INVEN;
				else if (e1 <= e2) player->upkeep->command_wrk = USE_EQUIP;
			} else {
				if (e1 <= e2) player->upkeep->command_wrk = USE_EQUIP;
				else if (i1 <= i2) player->upkeep->command_wrk = USE_INVEN;
				else if (q1 <= q2) player->upkeep->command_wrk = USE_QUIVER;
			}
		}

		newmenu = true;
	}

	/* Result */
	return selection;
}
예제 #12
0
/**
 * Create a new store.
 */
static struct store *store_new(int idx) {
	struct store *s = mem_zalloc(sizeof *s);
	s->sidx = idx;
	s->stock_size = z_info->store_inven_max;
	return s;
}
예제 #13
0
static void monmsg_init(void) {
    /* Array of stacked monster messages */
    mon_msg = mem_zalloc(MAX_STORED_MON_MSG * sizeof(monster_race_message));
    mon_message_hist = mem_zalloc(MAX_STORED_MON_CODES *
                                  sizeof(monster_message_history));
}
예제 #14
0
int audiosess_alloc(struct audiosess_st **stp,
		    audiosess_int_h *inth, void *arg)
{
	struct audiosess_st *st = NULL;
	struct audiosess *as = NULL;
	int err = 0;
	bool created = false;
#if TARGET_OS_IPHONE
	AudioSessionPropertyID id = kAudioSessionProperty_AudioRouteChange;
	UInt32 category;
	OSStatus ret;
#endif

	if (!stp)
		return EINVAL;

#if TARGET_OS_IPHONE
	/* Must be done for all modules */
	category = kAudioSessionCategory_PlayAndRecord;
	ret = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,
				      sizeof(category), &category);
	if (ret) {
		re_fprintf(stderr, "Audio Category: %d\n", ret);
		return EINVAL;
	}
#endif

	if (gas)
		goto makesess;

	as = mem_zalloc(sizeof(*as), destructor);
	if (!as)
		return ENOMEM;

#if TARGET_OS_IPHONE
	ret = AudioSessionSetActive(true);
	if (ret) {
		re_fprintf(stderr, "AudioSessionSetActive: %d\n", ret);
		err = ENOSYS;
		goto out;
	}

	ret = AudioSessionAddPropertyListener(id, propListener, as);
	if (ret) {
		re_fprintf(stderr, "AudioSessionAddPropertyListener: %d\n",
			   ret);
		err = EINVAL;
		goto out;
	}
#endif

	gas = as;
	created = true;

 makesess:
	st = mem_zalloc(sizeof(*st), sess_destructor);
	if (!st) {
		err = ENOMEM;
		goto out;
	}
	st->inth = inth;
	st->arg = arg;
	st->as = created ? gas : mem_ref(gas);

	list_append(&gas->sessl, &st->le, st);

 out:
	if (err) {
		mem_deref(as);
		mem_deref(st);
	}
	else {
		*stp = st;
	}

	return err;
}
예제 #15
0
파일: parser.c 프로젝트: Colt374/angband
struct parser *parser_new(void) {
	struct parser *p = mem_zalloc(sizeof *p);
	return p;
}
예제 #16
0
파일: gst.c 프로젝트: alfredh/baresip
static int gst_alloc(struct ausrc_st **stp, const struct ausrc *as,
		     struct media_ctx **ctx,
		     struct ausrc_prm *prm, const char *device,
		     ausrc_read_h *rh, ausrc_error_h *errh, void *arg)
{
	struct ausrc_st *st;
	int err;

	(void)ctx;

	if (!device)
		device = gst_uri;

	if (!prm)
		return EINVAL;

	if (prm->fmt != AUFMT_S16LE) {
		warning("gst: unsupported sample format (%s)\n",
			aufmt_name(prm->fmt));
		return ENOTSUP;
	}

	st = mem_zalloc(sizeof(*st), gst_destructor);
	if (!st)
		return ENOMEM;

	st->as   = as;
	st->rh   = rh;
	st->errh = errh;
	st->arg  = arg;

	err = str_dup(&st->uri, device);
	if (err)
		goto out;

	st->prm   = *prm;

	st->sampc = prm->srate * prm->ch * prm->ptime / 1000;
	st->psize = 2 * st->sampc;

	err = aubuf_alloc(&st->aubuf, st->psize, 0);
	if (err)
		goto out;

	err = gst_setup(st);
	if (err)
		goto out;

	st->run  = true;
	err = pthread_create(&st->tid, NULL, thread, st);
	if (err) {
		st->run = false;
		goto out;
	}

 out:
	if (err)
		mem_deref(st);
	else
		*stp = st;

	return err;
}
예제 #17
0
파일: avf.c 프로젝트: erezool/baresip
static int alloc(struct vidsrc_st **stp, struct vidsrc *vs,
		 struct media_ctx **mctx, struct vidsrc_prm *prm,
		 const struct vidsz *size, const char *fmt,
		 const char *dev, vidsrc_frame_h *frameh,
		 vidsrc_error_h *errorh, void *arg)
{
#if LIBAVFORMAT_VERSION_INT < ((52<<16) + (110<<8) + 0)
	AVFormatParameters prms;
#endif
	struct vidsrc_st *st;
	bool found_stream = false;
	uint32_t i;
	int ret, err = 0;

	(void)mctx;
	(void)errorh;

	if (!stp || !size || !frameh)
		return EINVAL;

	st = mem_zalloc(sizeof(*st), destructor);
	if (!st)
		return ENOMEM;

	st->vs     = mem_ref(vs);
	st->app_sz = *size;
	st->frameh = frameh;
	st->arg    = arg;

	if (prm) {
		st->fps = prm->fps;
	}
	else {
		st->fps = 25;
	}

	/*
	 * avformat_open_input() was added in lavf 53.2.0 according to
	 * ffmpeg/doc/APIchanges
	 */

#if LIBAVFORMAT_VERSION_INT >= ((52<<16) + (110<<8) + 0)
	(void)fmt;
	ret = avformat_open_input(&st->ic, dev, NULL, NULL);
#else

	/* Params */
	memset(&prms, 0, sizeof(prms));

	prms.time_base          = (AVRational){1, st->fps};
	prms.channels           = 1;
	prms.width              = size->w;
	prms.height             = size->h;
	prms.pix_fmt            = PIX_FMT_YUV420P;
	prms.channel            = 0;

	ret = av_open_input_file(&st->ic, dev, av_find_input_format(fmt),
				 0, &prms);
#endif

	if (ret < 0) {
		err = ENOENT;
		goto out;
	}

#if LIBAVFORMAT_VERSION_INT >= ((53<<16) + (4<<8) + 0)
	ret = avformat_find_stream_info(st->ic, NULL);
#else
	ret = av_find_stream_info(st->ic);
#endif

	if (ret < 0) {
		warning("avformat: %s: no stream info\n", dev);
		err = ENOENT;
		goto out;
	}

#if 0
	dump_format(st->ic, 0, dev, 0);
#endif

	for (i=0; i<st->ic->nb_streams; i++) {
		const struct AVStream *strm = st->ic->streams[i];
		AVCodecContext *ctx = strm->codec;

		if (ctx->codec_type != AVMEDIA_TYPE_VIDEO)
			continue;

		debug("avformat: stream %u:  %u x %u "
		      "  time_base=%d/%d\n",
		      i, ctx->width, ctx->height,
		      ctx->time_base.num, ctx->time_base.den);

		st->sz.w   = ctx->width;
		st->sz.h   = ctx->height;
		st->ctx    = ctx;
		st->sindex = strm->index;

		if (ctx->codec_id != AV_CODEC_ID_NONE) {

			st->codec = avcodec_find_decoder(ctx->codec_id);
			if (!st->codec) {
				err = ENOENT;
				goto out;
			}

#if LIBAVCODEC_VERSION_INT >= ((53<<16)+(8<<8)+0)
			ret = avcodec_open2(ctx, st->codec, NULL);
#else
			ret = avcodec_open(ctx, st->codec);
#endif
			if (ret < 0) {
				err = ENOENT;
				goto out;
			}
		}

		found_stream = true;
		break;
	}

	if (!found_stream) {
		err = ENOENT;
		goto out;
	}

	st->run = true;
	err = pthread_create(&st->thread, NULL, read_thread, st);
	if (err) {
		st->run = false;
		goto out;
	}

 out:
	if (err)
		mem_deref(st);
	else
		*stp = st;

	return err;
}
예제 #18
0
파일: encode.c 프로젝트: lmangani/baresip
int opus_encode_update(struct auenc_state **aesp, const struct aucodec *ac,
		       struct auenc_param *param, const char *fmtp)
{
	struct auenc_state *aes;
	struct opus_param prm, conf_prm;
	opus_int32 fch, vbr;
	const struct aucodec *auc = ac;

	(void)param;

	if (!aesp || !ac || !ac->ch)
		return EINVAL;

	debug("opus: encoder fmtp (%s)\n", fmtp);

	/* Save the incoming OPUS parameters from SDP offer */
	if (str_isset(fmtp)) {
		opus_mirror_params(fmtp);
	}

	aes = *aesp;

	if (!aes) {
		const opus_int32 complex = 10;
		int opuserr;

		aes = mem_zalloc(sizeof(*aes), destructor);
		if (!aes)
			return ENOMEM;

		aes->ch = ac->ch;

		aes->enc = opus_encoder_create(ac->srate, ac->ch,
					       /* this has big impact on cpu */
					       OPUS_APPLICATION_AUDIO,
					       &opuserr);
		if (!aes->enc) {
			warning("opus: encoder create: %s\n",
				opus_strerror(opuserr));
			mem_deref(aes);
			return ENOMEM;
		}

		(void)opus_encoder_ctl(aes->enc, OPUS_SET_COMPLEXITY(complex));

		*aesp = aes;
	}

	prm.srate      = 48000;
	prm.bitrate    = OPUS_AUTO;
	prm.stereo     = 1;
	prm.cbr        = 0;
	prm.inband_fec = 0;
	prm.dtx        = 0;

	opus_decode_fmtp(&prm, fmtp);

	conf_prm.bitrate = OPUS_AUTO;
	opus_decode_fmtp(&conf_prm, auc->fmtp);

	if ((prm.bitrate == OPUS_AUTO) ||
	    ((conf_prm.bitrate != OPUS_AUTO) &&
	     (conf_prm.bitrate < prm.bitrate)))
		prm.bitrate = conf_prm.bitrate;

	fch = prm.stereo ? OPUS_AUTO : 1;
	vbr = prm.cbr ? 0 : 1;

	(void)opus_encoder_ctl(aes->enc,
			       OPUS_SET_MAX_BANDWIDTH(srate2bw(prm.srate)));
	(void)opus_encoder_ctl(aes->enc, OPUS_SET_BITRATE(prm.bitrate));
	(void)opus_encoder_ctl(aes->enc, OPUS_SET_FORCE_CHANNELS(fch));
	(void)opus_encoder_ctl(aes->enc, OPUS_SET_VBR(vbr));
	(void)opus_encoder_ctl(aes->enc, OPUS_SET_INBAND_FEC(prm.inband_fec));
	(void)opus_encoder_ctl(aes->enc, OPUS_SET_DTX(prm.dtx));


#if 0
	{
	opus_int32 bw, complex;

	(void)opus_encoder_ctl(aes->enc, OPUS_GET_MAX_BANDWIDTH(&bw));
	(void)opus_encoder_ctl(aes->enc, OPUS_GET_BITRATE(&prm.bitrate));
	(void)opus_encoder_ctl(aes->enc, OPUS_GET_FORCE_CHANNELS(&fch));
	(void)opus_encoder_ctl(aes->enc, OPUS_GET_VBR(&vbr));
	(void)opus_encoder_ctl(aes->enc, OPUS_GET_INBAND_FEC(&prm.inband_fec));
	(void)opus_encoder_ctl(aes->enc, OPUS_GET_DTX(&prm.dtx));
	(void)opus_encoder_ctl(aes->enc, OPUS_GET_COMPLEXITY(&complex));

	debug("opus: encode bw=%s bitrate=%i fch=%s "
	      "vbr=%i fec=%i dtx=%i complex=%i\n",
	      bwname(bw), prm.bitrate, chname(fch),
	      vbr, prm.inband_fec, prm.dtx, complex);
	}
#endif

	return 0;
}
예제 #19
0
파일: audio.c 프로젝트: quentusrex/baresip
int audio_alloc(struct audio **ap, const struct config *cfg,
		struct call *call, struct sdp_session *sdp_sess, int label,
		const struct mnat *mnat, struct mnat_sess *mnat_sess,
		const struct menc *menc, struct menc_sess *menc_sess,
		uint32_t ptime, const struct list *aucodecl,
		audio_event_h *eventh, audio_err_h *errh, void *arg)
{
	struct audio *a;
	struct autx *tx;
	struct aurx *rx;
	struct le *le;
	int err;

	if (!ap || !cfg)
		return EINVAL;

	a = mem_zalloc(sizeof(*a), audio_destructor);
	if (!a)
		return ENOMEM;

	MAGIC_INIT(a);

	a->cfg = cfg->audio;
	tx = &a->tx;
	rx = &a->rx;

	err = stream_alloc(&a->strm, &cfg->avt, call, sdp_sess,
			   "audio", label,
			   mnat, mnat_sess, menc, menc_sess,
			   call_localuri(call),
			   stream_recv_handler, NULL, a);
	if (err)
		goto out;

	if (cfg->avt.rtp_bw.max) {
		stream_set_bw(a->strm, AUDIO_BANDWIDTH);
	}

	err = sdp_media_set_lattr(stream_sdpmedia(a->strm), true,
				  "ptime", "%u", ptime);
	if (err)
		goto out;

	/* Audio codecs */
	for (le = list_head(aucodecl); le; le = le->next) {
		err = add_audio_codec(a, stream_sdpmedia(a->strm), le->data);
		if (err)
			goto out;
	}

	tx->mb = mbuf_alloc(STREAM_PRESZ + 4096);
	tx->sampv = mem_zalloc(AUDIO_SAMPSZ * 2, NULL);
	rx->sampv = mem_zalloc(AUDIO_SAMPSZ * 2, NULL);
	if (!tx->mb || !tx->sampv || !rx->sampv) {
		err = ENOMEM;
		goto out;
	}

	err = telev_alloc(&a->telev, TELEV_PTIME);
	if (err)
		goto out;

	err = add_telev_codec(a);
	if (err)
		goto out;

	auresamp_init(&tx->resamp);
	str_ncpy(tx->device, a->cfg.src_dev, sizeof(tx->device));
	tx->ptime  = ptime;
	tx->ts     = rand_u16();
	tx->marker = true;

	auresamp_init(&rx->resamp);
	str_ncpy(rx->device, a->cfg.play_dev, sizeof(rx->device));
	rx->pt     = -1;
	rx->ptime  = ptime;

	a->eventh  = eventh;
	a->errh    = errh;
	a->arg     = arg;

	if (a->cfg.txmode == AUDIO_MODE_TMR)
		tmr_init(&tx->u.tmr);

 out:
	if (err)
		mem_deref(a);
	else
		*ap = a;

	return err;
}
예제 #20
0
파일: reg.c 프로젝트: JackKingChen/unitest
/**
 * Allocate a SIP Registration client
 *
 * @param regp     Pointer to allocated SIP Registration client
 * @param sip      SIP Stack instance
 * @param reg_uri  SIP Request URI
 * @param to_uri   SIP To-header URI
 * @param from_uri SIP From-header URI
 * @param expires  Registration interval in [seconds]
 * @param cuser    Contact username
 * @param routev   Optional route vector
 * @param routec   Number of routes
 * @param regid    Register identification
 * @param authh    Authentication handler
 * @param aarg     Authentication handler argument
 * @param aref     True to ref argument
 * @param resph    Response handler
 * @param arg      Response handler argument
 * @param params   Optional Contact-header parameters
 * @param fmt      Formatted strings with extra SIP Headers
 *
 * @return 0 if success, otherwise errorcode
 */
int sipreg_register(struct sipreg **regp, struct sip *sip, const char *reg_uri,
		    const char *to_uri, const char *from_uri, uint32_t expires,
		    const char *cuser, const char *routev[], uint32_t routec,
		    int regid, sip_auth_h *authh, void *aarg, bool aref,
		    sip_resp_h *resph, void *arg,
		    const char *params, const char *fmt, ...)
{
	struct sipreg *reg;
	int err;

	if (!regp || !sip || !reg_uri || !to_uri || !from_uri ||
	    !expires || !cuser)
		return EINVAL;

	reg = mem_zalloc(sizeof(*reg), destructor);
	if (!reg)
		return ENOMEM;

	err = sip_dialog_alloc(&reg->dlg, reg_uri, to_uri, NULL, from_uri,
			       routev, routec);
	if (err)
		goto out;

	err = sip_auth_alloc(&reg->auth, authh, aarg, aref);
	if (err)
		goto out;

	err = str_dup(&reg->cuser, cuser);
	if (params)
		err |= str_dup(&reg->params, params);
	if (err)
		goto out;

	/* Custom SIP headers */
	if (fmt) {
		va_list ap;

		reg->hdrs = mbuf_alloc(256);
		if (!reg->hdrs) {
			err = ENOMEM;
			goto out;
		}

		va_start(ap, fmt);
		err = mbuf_vprintf(reg->hdrs, fmt, ap);
		reg->hdrs->pos = 0;
		va_end(ap);

		if (err)
			goto out;
	}

	reg->sip     = mem_ref(sip);
	reg->expires = expires;
	reg->resph   = resph ? resph : dummy_handler;
	reg->arg     = arg;
	reg->regid   = regid;

	err = request(reg, true);
	if (err)
		goto out;

 out:
	if (err)
		mem_deref(reg);
	else
		*regp = reg;

	return err;
}
예제 #21
0
파일: audio.c 프로젝트: quentusrex/baresip
static int start_source(struct autx *tx, struct audio *a)
{
	const struct aucodec *ac = tx->ac;
	uint32_t srate_dsp = get_srate(ac);
	uint32_t channels_dsp;
	bool resamp = false;
	int err;

	if (!ac)
		return 0;

	channels_dsp = ac->ch;

	if (a->cfg.srate_src && a->cfg.srate_src != srate_dsp) {
		resamp = true;
		srate_dsp = a->cfg.srate_src;
	}
	if (a->cfg.channels_src && a->cfg.channels_src != channels_dsp) {
		resamp = true;
		channels_dsp = a->cfg.channels_src;
	}

	/* Optional resampler, if configured */
	if (resamp && !tx->sampv_rs) {

		info("audio: enable ausrc resampler:"
		     " %uHz/%uch <-- %uHz/%uch\n",
		     get_srate(ac), ac->ch, srate_dsp, channels_dsp);

		tx->sampv_rs = mem_zalloc(AUDIO_SAMPSZ * 2, NULL);
		if (!tx->sampv_rs)
			return ENOMEM;

		err = auresamp_setup(&tx->resamp,
				     srate_dsp, channels_dsp,
				     get_srate(ac), ac->ch);
		if (err) {
			warning("audio: could not setup ausrc resampler"
				" (%m)\n", err);
			return err;
		}
	}

	/* Start Audio Source */
	if (!tx->ausrc && ausrc_find(NULL)) {

		struct ausrc_prm prm;

		prm.srate      = srate_dsp;
		prm.ch         = channels_dsp;
		prm.ptime      = tx->ptime;

		tx->psize = 2 * calc_nsamp(prm.srate, prm.ch, prm.ptime);

		if (!tx->aubuf) {
			err = aubuf_alloc(&tx->aubuf, tx->psize * 2,
					  tx->psize * 30);
			if (err)
				return err;
		}

		err = ausrc_alloc(&tx->ausrc, NULL, a->cfg.src_mod,
				  &prm, tx->device,
				  ausrc_read_handler, ausrc_error_handler, a);
		if (err) {
			warning("audio: start_source failed (%s.%s): %m\n",
				a->cfg.src_mod, tx->device, err);
			return err;
		}

		switch (a->cfg.txmode) {
#ifdef HAVE_PTHREAD
		case AUDIO_MODE_THREAD:
		case AUDIO_MODE_THREAD_REALTIME:
			if (!tx->u.thr.run) {
				tx->u.thr.run = true;
				err = pthread_create(&tx->u.thr.tid, NULL,
						     tx_thread, a);
				if (err) {
					tx->u.thr.tid = false;
					return err;
				}
			}
			break;
#endif

		case AUDIO_MODE_TMR:
			tmr_start(&tx->u.tmr, 1, timeout_tx, a);
			break;

		default:
			break;
		}
	}

	return 0;
}
예제 #22
0
int sdp_format_add(struct sdp_format **fmtp, struct sdp_media *m,
		   bool prepend, const char *id, const char *name,
		   uint32_t srate, uint8_t ch,
		   sdp_fmtp_cmp_h *cmph, void *data, bool ref,
		   const char *params, ...)
{
	struct sdp_format *fmt;
	int err;

	if (!m)
		return EINVAL;

	if (!id && (m->dynpt > RTP_DYNPT_END))
		return ERANGE;

	fmt = mem_zalloc(sizeof(*fmt), destructor);
	if (!fmt)
		return ENOMEM;

	if (prepend)
		list_prepend(&m->lfmtl, &fmt->le, fmt);
	else
		list_append(&m->lfmtl, &fmt->le, fmt);

	if (id)
		err = str_dup(&fmt->id, id);
	else
		err = re_sdprintf(&fmt->id, "%i", m->dynpt++);
	if (err)
		goto out;

	if (name) {
		err = str_dup(&fmt->name, name);
		if (err)
			goto out;
	}

	if (params) {
		va_list ap;

		va_start(ap, params);
		err = re_vsdprintf(&fmt->params, params, ap);
		va_end(ap);

		if (err)
			goto out;
	}

	fmt->pt    = atoi(fmt->id);
	fmt->srate = srate;
	fmt->ch    = ch;
	fmt->cmph  = cmph;
	fmt->data  = ref ? mem_ref(data) : data;
	fmt->ref   = ref;
	fmt->sup   = true;

 out:
	if (err)
		mem_deref(fmt);
	else if (fmtp)
		*fmtp = fmt;

	return err;
}
예제 #23
0
int mpa_decode_update(struct audec_state **adsp, const struct aucodec *ac,
		       const char *fmtp)
{
	struct audec_state *ads;
	int result, err=0;
	(void)fmtp;

	if (!adsp || !ac || !ac->ch)
		return EINVAL;

	ads = *adsp;

#ifdef DEBUG
	debug("MPA dec created %s\n",fmtp);
#endif

	if (!ads) {
		ads = mem_zalloc(sizeof(*ads), destructor);
		if (!ads)
			return ENOMEM;
	}
	else {
		memset(ads,0,sizeof(*ads));
	}
	ads->channels = 0;
	ads->resampler = NULL;
	ads->start = 0;

	ads->dec = mpg123_new(NULL,&result);
	if (!ads->dec) {
		warning("MPA dec create: %s\n",
			mpg123_plain_strerror(result));
		err = ENOMEM;
		goto out;
	}

#ifdef DEBUG
	result = mpg123_param(ads->dec, MPG123_VERBOSE, 4, 4.);
#else
	result = mpg123_param(ads->dec, MPG123_VERBOSE, 0, 0.);
#endif
	if (result != MPG123_OK) {
		warning("MPA dec param error %s\n",
			mpg123_plain_strerror(result));
		err = EINVAL;
		goto out;
	}


	result = mpg123_format_all(ads->dec);
	if (result != MPG123_OK) {
		warning("MPA dec format error %s\n",
			mpg123_plain_strerror(result));
		err = EINVAL;
		goto out;
	}

	result = mpg123_open_feed(ads->dec);
	if (result != MPG123_OK) {
		warning("MPA dec open feed error %s\n",
			mpg123_plain_strerror(result));
		err = EINVAL;
		goto out;
	}

 out:
	if (err)
		mem_deref(ads);
	else
		*adsp = ads;

	return err;
}
예제 #24
0
int coreaudio_player_alloc(struct auplay_st **stp, struct auplay *ap,
			   struct auplay_prm *prm, const char *device,
			   auplay_write_h *wh, void *arg)
{
	AudioStreamBasicDescription fmt;
	struct auplay_st *st;
	uint32_t bytc, i;
	OSStatus status;
	int err;

	(void)device;

	st = mem_zalloc(sizeof(*st), auplay_destructor);
	if (!st)
		return ENOMEM;

	st->ap  = mem_ref(ap);
	st->wh  = wh;
	st->arg = arg;

	err = pthread_mutex_init(&st->mutex, NULL);
	if (err)
		goto out;

	err = audio_session_enable();
	if (err)
		goto out;

	fmt.mSampleRate       = (Float64)prm->srate;
	fmt.mFormatID         = audio_fmt(prm->fmt);
	fmt.mFormatFlags      = kLinearPCMFormatFlagIsSignedInteger |
		                kAudioFormatFlagIsPacked;
#ifdef __BIG_ENDIAN__
	fmt.mFormatFlags     |= kAudioFormatFlagIsBigEndian;
#endif
	fmt.mFramesPerPacket  = 1;
	fmt.mBytesPerFrame    = prm->ch * bytesps(prm->fmt);
	fmt.mBytesPerPacket   = prm->ch * bytesps(prm->fmt);
	fmt.mChannelsPerFrame = prm->ch;
	fmt.mBitsPerChannel   = 8*bytesps(prm->fmt);

	status = AudioQueueNewOutput(&fmt, play_handler, st, NULL,
				     kCFRunLoopCommonModes, 0, &st->queue);
	if (status) {
		re_fprintf(stderr, "AudioQueueNewOutput error: %i\n", status);
		err = ENODEV;
		goto out;
	}

	bytc = prm->frame_size * bytesps(prm->fmt);

	for (i=0; i<ARRAY_SIZE(st->buf); i++)  {

		status = AudioQueueAllocateBuffer(st->queue, bytc,
						  &st->buf[i]);
		if (status)  {
			err = ENOMEM;
			goto out;
		}

		st->buf[i]->mAudioDataByteSize = bytc;

		memset(st->buf[i]->mAudioData, 0,
		       st->buf[i]->mAudioDataByteSize);

		(void)AudioQueueEnqueueBuffer(st->queue, st->buf[i], 0, NULL);
	}

	status = AudioQueueStart(st->queue, NULL);
	if (status)  {
		re_fprintf(stderr, "AudioQueueStart error %i\n", status);
		err = ENODEV;
		goto out;
	}

 out:
	if (err)
		mem_deref(st);
	else
		*stp = st;

	return err;
}
예제 #25
0
static int poll_init(struct re *re)
{
	DEBUG_INFO("poll init (maxfds=%d)\n", re->maxfds);

	if (!re->maxfds) {
		DEBUG_WARNING("poll init: maxfds is 0\n");
		return EINVAL;
	}

	switch (re->method) {

#ifdef HAVE_POLL
	case METHOD_POLL:
		if (!re->fds) {
			re->fds = mem_zalloc(re->maxfds * sizeof(*re->fds),
					    NULL);
			if (!re->fds)
				return ENOMEM;
		}
		break;
#endif
#ifdef HAVE_EPOLL
	case METHOD_EPOLL:
		if (!re->events) {
			DEBUG_INFO("allocate %u bytes for epoll set\n",
				   re->maxfds * sizeof(*re->events));
			re->events = mem_zalloc(re->maxfds*sizeof(*re->events),
					      NULL);
			if (!re->events)
				return ENOMEM;
		}

		if (re->epfd < 0
		    && -1 == (re->epfd = epoll_create(re->maxfds))) {

			int err = errno;

			DEBUG_WARNING("epoll_create: %m (maxfds=%d)\n",
				      err, re->maxfds);
			return err;
		}
		DEBUG_INFO("init: epoll_create() epfd=%d\n", re->epfd);
		break;
#endif

#ifdef HAVE_KQUEUE
	case METHOD_KQUEUE:

		if (!re->evlist) {
			size_t sz = re->maxfds * sizeof(*re->evlist);
			re->evlist = mem_zalloc(sz, NULL);
			if (!re->evlist)
				return ENOMEM;
		}

		if (re->kqfd < 0) {
			re->kqfd = kqueue();
			if (re->kqfd < 0)
				return errno;
			DEBUG_INFO("kqueue: fd=%d\n", re->kqfd);
		}

		break;
#endif

	default:
		break;
	}
	return 0;
}
예제 #26
0
/**
 * Allocate a SIP User-Agent
 *
 * @param uap   Pointer to allocated User-Agent object
 * @param aor   SIP Address-of-Record (AOR)
 *
 * @return 0 if success, otherwise errorcode
 */
int ua_alloc(struct ua **uap, const char *aor)
{
	struct ua *ua;
	int err;
  info("baresip.ua.ua_alloc(), with aor=%s\n", aor);

	if (!aor)
		return EINVAL;

	ua = mem_zalloc(sizeof(*ua), ua_destructor);
	if (!ua)
		return ENOMEM;

	MAGIC_INIT(ua);

	list_init(&ua->calls);

#if HAVE_INET6
	ua->af   = uag.prefer_ipv6 ? AF_INET6 : AF_INET;
#else
	ua->af   = AF_INET;
#endif

	/* Decode SIP address */

	err = account_alloc(&ua->acc, aor);
	if (err)
		goto out;

	/* generate a unique contact-user, this is needed to route
	   incoming requests when using multiple useragents */
	err = re_sdprintf(&ua->cuser, "%r-%p", &ua->acc->luri.user, ua);
	if (err)
		goto out;

	if (ua->acc->sipnat) {
		ua_printf(ua, "Using sipnat: `%s'\n", ua->acc->sipnat);
	}

	if (ua->acc->mnat) {
		ua_printf(ua, "Using medianat `%s'\n",
			  ua->acc->mnat->id);

		if (0 == str_casecmp(ua->acc->mnat->id, "ice"))
			add_extension(ua, "ice");
	}

	if (ua->acc->menc) {
		ua_printf(ua, "Using media encryption `%s'\n",
			  ua->acc->menc->id);
	}

	/* Register clients */
	if (str_isset(uag.cfg->uuid))
	        add_extension(ua, "gruu");

	if (0 == str_casecmp(ua->acc->sipnat, "outbound")) {

		size_t i;

		add_extension(ua, "path");
		add_extension(ua, "outbound");

		if (!str_isset(uag.cfg->uuid)) {

			warning("ua: outbound requires valid UUID!\n");
			err = ENOSYS;
			goto out;
		}

		for (i=0; i<ARRAY_SIZE(ua->acc->outbound); i++) {

			if (ua->acc->outbound[i] && ua->acc->regint) {
				err = reg_add(&ua->regl, ua, (int)i+1);
				if (err)
					break;
			}
		}
	}
	else if (ua->acc->regint) {
		err = reg_add(&ua->regl, ua, 0);
	}
	if (err)
		goto out;

	list_append(&uag.ual, &ua->le, ua);

	if (ua->acc->regint) {
		err = ua_register(ua);
	}

	if (!uag_current())
		uag_current_set(ua);

 out:
	if (err)
		mem_deref(ua);
	else if (uap) {
		*uap = ua;

		ua->uap = uap;
	}

	return err;
}
예제 #27
0
/**
 * Parse common command line arguments.
 * @param c The command line short argument
 * @param oparg Argument for the parameter, if any
 * @param ctx Pointer to the common context which is filled according
 * to command line parameters.
 * @return 0 if argument is parsed, -1 if error occurred, -2 if 
 * command line parameter was unknown.
 */
int common_parse_args(int c, char *arg, struct common_context *ctx)
{
        auth_ret_t auth_ret;
        uint16_t streams;
#ifdef DEBUG
        uint16_t debug_level = DEBUG_DEFAULT_LEVEL;
#endif /* DEBUG */

        if (c == -1)
                return 0;

        switch(c) {
                case 'S' :
                        ctx->options = set_flag( ctx->options, SEQ_FLAG );
                        break;
                case 'e' :
                        ctx->options = set_flag( ctx->options, ECHO_FLAG );
                        break;
                case 'v' :
                        ctx->options = set_flag( ctx->options, VERBOSE_FLAG);
                        break;
                case 'x' :
                        ctx->options = set_flag(ctx->options, XDUMP_FLAG);
                        break;
                case 'I' :
                        if (parse_uint16(arg, &streams) < 0 ) {
                                fprintf(stderr,
                                        "Invalid input stream count given\n");
                                return -1;
                        }
                        if (ctx->initmsg == NULL )
                                ctx->initmsg = mem_zalloc(sizeof(struct sctp_initmsg));

                        ctx->initmsg->sinit_max_instreams = streams;
                        break;
                case 'O' :
                        if (parse_uint16(arg, &streams) < 0 ) {
                                fprintf(stderr,
                                       "Invalid output stream count given\n");
                                return -1;
                        }
                        if (ctx->initmsg == NULL)
                                ctx->initmsg = mem_zalloc(sizeof(*ctx->initmsg));

                        ctx->initmsg->sinit_num_ostreams = streams;
                        break;
#ifdef DEBUG
                case 'D' :
                        if (parse_uint16(arg, &debug_level) < 0) {
                                fprintf(stderr,"Malformed Debug level number given\n");
                                return -1;
                        }
                        if (debug_level > DBG_L_ERR) {
                                fprintf(stderr, "Invalid debug level (expected 0-3)\n");
                                return -1;
                        }
                        DBG_LEVEL(debug_level);
                        break;
#endif /* DEBUG */
                case 'A' :
                        if (ctx->actx == NULL) {
                                ctx->actx = auth_create_context();
                                ctx->options = set_flag(ctx->options, AUTH_FLAG);
                        }
                        auth_ret = auth_parse_key(ctx->actx, arg);
                        if (auth_ret == AUTHERR_INVALID_PARAM) {
                                fprintf(stderr,"Invalid key given\n");
                                return -1;
                        }
                        break;
                case 'C' :
                        if (ctx->actx == NULL) {
                                ctx->actx = auth_create_context();
                                ctx->options = set_flag(ctx->options, AUTH_FLAG);
                        }
                        auth_ret = auth_parse_chunk(ctx->actx, arg);
                        if (auth_ret == AUTHERR_INVALID_PARAM) {
                                fprintf(stderr,"Invalid chunk type given\n");
                                return -1;
                        } else if (auth_ret == AUTHERR_UNSUPPORTED_PARAM) {
                                fprintf(stderr,"Given chunk type not supported for authentication\n");
                                return -1;
                        }
                        break;
                case 'M' :
                        if (ctx->actx == NULL) {
                                ctx->actx = auth_create_context();
                                ctx->options = set_flag(ctx->options, AUTH_FLAG);
                        }
                        auth_ret = auth_parse_hmac(ctx->actx, arg);
                        if (auth_ret == AUTHERR_INVALID_PARAM) {
                                fprintf(stderr,"Invalid hmac type given\n");
                                return -1;
                        } else if (auth_ret == AUTHERR_UNSUPPORTED_PARAM) {
                                fprintf(stderr, "HMAC %s is not supported\n",
                                                arg);
                                return -1;
                        }
                        break;
                default :
                        return -2;
        }
        return 0;
}
예제 #28
0
파일: panel.c 프로젝트: AmesianX/baresip
int panel_alloc(struct panel **panelp, const char *label,
		unsigned yoffs, int width, int height)
{
	struct panel *panel;
	int err;

	if (!panelp || !width || !height)
		return EINVAL;

	panel = mem_zalloc(sizeof(*panel), destructor);
	if (!panel)
		return ENOMEM;

	err = str_dup(&panel->label, label);
	if (err)
		goto out;

	panel->size.w = width;
	panel->size.h = height;
	panel->yoffs = yoffs;
	panel->xoffs = TEXT_WIDTH;

	panel->size_text.w = TEXT_WIDTH;
	panel->size_text.h = height;

	panel->surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
						    panel->size_text.w,
						    panel->size_text.h);
	panel->cr = cairo_create(panel->surface);
	if (!panel->surface || !panel->cr) {
		warning("vidinfo: cairo error\n");
		return ENOMEM;
	}

	cairo_select_font_face (panel->cr, "Hyperfont",
				CAIRO_FONT_SLANT_NORMAL,
				CAIRO_FONT_WEIGHT_NORMAL);
	cairo_set_font_size (panel->cr, height-2);

	panel->rrdc  = 0;
	panel->rrdsz = (width - TEXT_WIDTH) / 2;
	panel->rrdv  = mem_reallocarray(NULL, panel->rrdsz,
					sizeof(*panel->rrdv), NULL);
	if (!panel->rrdv) {
		err = ENOMEM;
		goto out;
	}

	tmr_start(&panel->tmr, 0, tmr_handler, panel);

	info("new panel '%s' (%u x %u) with RRD size %u\n",
	     label, width, height, panel->rrdsz);

 out:
	if (err)
		mem_deref(panel);
	else
		*panelp = panel;

	return err;
}
예제 #29
0
static errr finish_parse_profile(struct parser *p) {
	struct cave_profile *n, *c = parser_priv(p);
	int i, num;

	z_info->profile_max = 0;
	/* Count the list */
	while (c) {
		struct room_profile *r = c->room_profiles;
		c->n_room_profiles = 0;

		z_info->profile_max++;
		c = c->next;
		while (r) {
			c->n_room_profiles++;
			r = r->next;
		}
	}

	/* Allocate the array and copy the records to it */
	cave_profiles = mem_zalloc(z_info->profile_max * sizeof(*c));
	num = z_info->profile_max - 1;
	for (c = parser_priv(p); c; c = n) {
		struct room_profile *r_new = NULL;

		/* Main record */
		memcpy(&cave_profiles[num], c, sizeof(*c));
		n = c->next;
		if (num < z_info->profile_max - 1)
			cave_profiles[num].next = &cave_profiles[num + 1];
		else
			cave_profiles[num].next = NULL;

		/* Count the room profiles */
		if (c->room_profiles) {
			struct room_profile *r = c->room_profiles;
			c->n_room_profiles = 0;

			while (r) {
				c->n_room_profiles++;
				r = r->next;
			}
		}

		/* Now allocate the room profile array */
		if (c->room_profiles) {
			struct room_profile *r_temp, *r_old = c->room_profiles;

			/* Allocate space and copy */
			r_new = mem_zalloc(c->n_room_profiles * sizeof(*r_new));
			for (i = 0; i < c->n_room_profiles; i++) {
				memcpy(&r_new[i], r_old, sizeof(*r_old));
				r_old = r_old->next;
				if (!r_old) break;
			}

			/* Make next point correctly */
			for (i = 0; i < c->n_room_profiles; i++)
				if (r_new[i].next)
					r_new[i].next = &r_new[i + 1];

			/* Tidy up */
			r_old = c->room_profiles;
			r_temp = r_old;
			while (r_temp) {
				r_temp = r_old->next;
				mem_free(r_old);
				r_old = r_temp;
			}
		}
		cave_profiles[num].room_profiles = r_new;
		cave_profiles[num].n_room_profiles = c->n_room_profiles;

		mem_free(c);
		num--;
	}

	parser_destroy(p);
	return 0;
}
예제 #30
0
파일: msg.c 프로젝트: Issic47/libre
static inline int hdr_add(struct sip_msg *msg, const struct pl *name,
			  enum sip_hdrid id, const char *p, ssize_t l,
			  bool atomic, bool line)
{
	struct sip_hdr *hdr;
	int err = 0;

	hdr = mem_zalloc(sizeof(*hdr), hdr_destructor);
	if (!hdr)
		return ENOMEM;

	hdr->name  = *name;
	hdr->val.p = p;
	hdr->val.l = MAX(l, 0);
	hdr->id    = id;

	switch (id) {

	case SIP_HDR_VIA:
	case SIP_HDR_ROUTE:
		if (!atomic)
			break;

		hash_append(msg->hdrht, id, &hdr->he, mem_ref(hdr));
		list_append(&msg->hdrl, &hdr->le, mem_ref(hdr));
		break;

	default:
		if (atomic)
			hash_append(msg->hdrht, id, &hdr->he, mem_ref(hdr));
		if (line)
			list_append(&msg->hdrl, &hdr->le, mem_ref(hdr));
		break;
	}

	/* parse common headers */
	switch (id) {

	case SIP_HDR_VIA:
		if (!atomic || pl_isset(&msg->via.sentby))
			break;

		err = sip_via_decode(&msg->via, &hdr->val);
		break;

	case SIP_HDR_TO:
		err = sip_addr_decode((struct sip_addr *)&msg->to, &hdr->val);
		if (err)
			break;

		(void)msg_param_decode(&msg->to.params, "tag", &msg->to.tag);
		msg->to.val = hdr->val;
		break;

	case SIP_HDR_FROM:
		err = sip_addr_decode((struct sip_addr *)&msg->from,
				      &hdr->val);
		if (err)
			break;

		(void)msg_param_decode(&msg->from.params, "tag",
				       &msg->from.tag);
		msg->from.val = hdr->val;
		break;

	case SIP_HDR_CALL_ID:
		msg->callid = hdr->val;
		break;

	case SIP_HDR_CSEQ:
		err = sip_cseq_decode(&msg->cseq, &hdr->val);
		break;

	case SIP_HDR_MAX_FORWARDS:
		msg->maxfwd = hdr->val;
		break;

	case SIP_HDR_CONTENT_TYPE:
		err = msg_ctype_decode(&msg->ctyp, &hdr->val);
		break;

	case SIP_HDR_CONTENT_LENGTH:
		msg->clen = hdr->val;
		break;

	case SIP_HDR_EXPIRES:
		msg->expires = hdr->val;
		break;

	default:
		/* re_printf("%r = %u\n", &hdr->name, id); */
		break;
	}

	mem_deref(hdr);

	return err;
}