Esempio n. 1
0
/**
 * Lookup a SIP uri in all registered contacts
 *
 * @param contacts Contacts container
 * @param uri      SIP uri to lookup
 *
 * @return Matching contact if found, otherwise NULL
 */
struct contact *contact_find(const struct contacts *contacts, const char *uri)
{
	if (!contacts)
		return NULL;

	return list_ledata(hash_lookup(contacts->cht, hash_joaat_str(uri),
				       find_handler, (void *)uri));
}
Esempio n. 2
0
int sip_ctrans_request(struct sip_ctrans **ctp, struct sip *sip,
		       enum sip_transp tp, const struct sa *dst, char *met,
		       char *branch, struct mbuf *mb,
		       sip_resp_h *resph, void *arg)
{
	struct sip_ctrans *ct;
	int err;

	if (!sip || !dst || !met || !branch || !mb)
		return EINVAL;

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

	hash_append(sip->ht_ctrans, hash_joaat_str(branch), &ct->he, ct);

	ct->invite = !strcmp(met, "INVITE");
	ct->branch = mem_ref(branch);
	ct->met    = mem_ref(met);
	ct->mb     = mem_ref(mb);
	ct->dst    = *dst;
	ct->tp     = tp;
	ct->sip    = sip;
	ct->state  = ct->invite ? CALLING : TRYING;
	ct->resph  = resph ? resph : dummy_handler;
	ct->arg    = arg;

	err = sip_transp_send(&ct->qent, sip, NULL, tp, dst, mb,
			      transport_handler, ct);
	if (err)
		goto out;

	tmr_start(&ct->tmr, 64 * SIP_T1, tmr_handler, ct);

	if (!sip_transp_reliable(ct->tp))
		tmr_start(&ct->tmre, SIP_T1, retransmit_handler, ct);

 out:
	if (err)
		mem_deref(ct);
	else if (ctp)
		*ctp = ct;

	return err;
}
Esempio n. 3
0
int device_connect(struct device **devp, const char *device,
		   struct auplay_st *auplay, struct ausrc_st *ausrc)
{
	struct device *dev;
	int err = 0;

	if (!devp)
		return EINVAL;
	if (!str_isset(device))
		return ENODEV;

	dev = find_device(device);
	if (dev) {
		*devp = mem_ref(dev);
	}
	else {
		dev = mem_zalloc(sizeof(*dev), destructor);
		if (!dev)
			return ENOMEM;

		str_ncpy(dev->name, device, sizeof(dev->name));

		hash_append(ht_device, hash_joaat_str(device), &dev->le, dev);

		*devp = dev;

		debug("aubridge: created device '%s'\n", device);
	}

	if (auplay)
		dev->auplay = auplay;
	if (ausrc)
		dev->ausrc = ausrc;

	/* wait until we have both SRC+PLAY */
	if (dev->ausrc && dev->auplay && !dev->run) {

		dev->run = true;
		err = pthread_create(&dev->thread, NULL, device_thread, dev);
		if (err) {
			dev->run = false;
		}
	}

	return err;
}
Esempio n. 4
0
int vidbridge_disp_alloc(struct vidisp_st **stp, const struct vidisp *vd,
                         struct vidisp_prm *prm, const char *dev,
                         vidisp_resize_h *resizeh, void *arg)
{
    struct vidisp_st *st;
    int err = 0;
    (void)prm;
    (void)resizeh;
    (void)arg;

    if (!stp || !vd || !dev)
        return EINVAL;

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

    st->vd = vd;

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

    /* find the vidsrc with the same device-name */
    st->vidsrc = vidbridge_src_find(dev);
    if (st->vidsrc) {
        st->vidsrc->vidisp = st;
    }

    hash_append(ht_disp, hash_joaat_str(dev), &st->le, st);

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

    return err;
}
Esempio n. 5
0
struct vidisp_st *vidbridge_disp_find(const char *device)
{
    return list_ledata(hash_lookup(ht_disp, hash_joaat_str(device),
                                   list_apply_handler, (void *)device));
}
Esempio n. 6
0
/**
 * Accept an incoming SIP Session connection
 *
 * @param sessp     Pointer to allocated SIP Session
 * @param sock      SIP Session socket
 * @param msg       Incoming SIP message
 * @param scode     Response status code
 * @param reason    Response reason phrase
 * @param cuser     Contact username
 * @param ctype     Session content-type
 * @param desc      Content description (e.g. SDP)
 * @param authh     SIP Authentication handler
 * @param aarg      Authentication handler argument
 * @param aref      True to mem_ref() aarg
 * @param offerh    Session offer handler
 * @param answerh   Session answer handler
 * @param estabh    Session established handler
 * @param infoh     Session info handler
 * @param referh    Session refer handler
 * @param closeh    Session close handler
 * @param arg       Handler argument
 * @param fmt       Formatted strings with extra SIP Headers
 *
 * @return 0 if success, otherwise errorcode
 */
int sipsess_accept(struct sipsess **sessp, struct sipsess_sock *sock,
		   const struct sip_msg *msg, uint16_t scode,
		   const char *reason, const char *cuser, const char *ctype,
		   struct mbuf *desc,
		   sip_auth_h *authh, void *aarg, bool aref,
		   sipsess_offer_h *offerh, sipsess_answer_h *answerh,
		   sipsess_estab_h *estabh, sipsess_info_h *infoh,
		   sipsess_refer_h *referh, sipsess_close_h *closeh,
		   void *arg, const char *fmt, ...)
{
	struct sipsess *sess;
	va_list ap;
	int err;

	if (!sessp || !sock || !msg || scode < 101 || scode > 299 ||
	    !cuser || !ctype)
		return EINVAL;

	err = sipsess_alloc(&sess, sock, cuser, ctype, NULL, authh, aarg, aref,
			    offerh, answerh, NULL, estabh, infoh, referh,
			    closeh, arg);
	if (err)
		return err;

	err = sip_dialog_accept(&sess->dlg, msg);
	if (err)
		goto out;

	hash_append(sock->ht_sess,
		    hash_joaat_str(sip_dialog_callid(sess->dlg)),
		    &sess->he, sess);

	sess->msg = mem_ref((void *)msg);

	err = sip_strans_alloc(&sess->st, sess->sip, msg, cancel_handler,
			       sess);
	if (err)
		goto out;

	va_start(ap, fmt);

	if (scode >= 200)
		err = sipsess_reply_2xx(sess, msg, scode, reason, desc,
					fmt, &ap);
	else
		err = sip_treplyf(&sess->st, NULL, sess->sip,
				  msg, true, scode, reason,
				  "Contact: <sip:%s@%J%s>\r\n"
				  "%v"
				  "%s%s%s"
				  "Content-Length: %zu\r\n"
				  "\r\n"
				  "%b",
				  sess->cuser, &msg->dst,
				  sip_transp_param(msg->tp),
				  fmt, &ap,
				  desc ? "Content-Type: " : "",
				  desc ? sess->ctype : "",
				  desc ? "\r\n" : "",
				  desc ? mbuf_get_left(desc) : (size_t)0,
				  desc ? mbuf_buf(desc) : NULL,
				  desc ? mbuf_get_left(desc) : (size_t)0);

	va_end(ap);

	if (err)
		goto out;

 out:
	if (err)
		mem_deref(sess);
	else
		*sessp = sess;

	return err;
}
Esempio n. 7
0
/**
 * Connect to a remote SIP useragent
 *
 * @param sessp     Pointer to allocated SIP Session
 * @param sock      SIP Session socket
 * @param to_uri    To SIP uri
 * @param from_name From display name
 * @param from_uri  From SIP uri
 * @param cuser     Contact username or URI
 * @param routev    Outbound route vector
 * @param routec    Outbound route vector count
 * @param ctype     Session content-type
 * @param desc      Content description (e.g. SDP)
 * @param authh     SIP Authentication handler
 * @param aarg      Authentication handler argument
 * @param aref      True to mem_ref() aarg
 * @param offerh    Session offer handler
 * @param answerh   Session answer handler
 * @param progrh    Session progress handler
 * @param estabh    Session established handler
 * @param infoh     Session info handler
 * @param referh    Session refer handler
 * @param closeh    Session close handler
 * @param arg       Handler argument
 * @param fmt       Formatted strings with extra SIP Headers
 *
 * @return 0 if success, otherwise errorcode
 */
int sipsess_connect(struct sipsess **sessp, struct sipsess_sock *sock,
		    const char *to_uri, const char *from_name,
		    const char *from_uri, const char *cuser,
		    const char *routev[], uint32_t routec,
		    const char *ctype, struct mbuf *desc,
		    sip_auth_h *authh, void *aarg, bool aref,
		    sipsess_offer_h *offerh, sipsess_answer_h *answerh,
		    sipsess_progr_h *progrh, sipsess_estab_h *estabh,
		    sipsess_info_h *infoh, sipsess_refer_h *referh,
		    sipsess_close_h *closeh, void *arg, const char *fmt, ...)
{
	struct sipsess *sess;
	int err;

	if (!sessp || !sock || !to_uri || !from_uri || !cuser || !ctype)
		return EINVAL;

	err = sipsess_alloc(&sess, sock, cuser, ctype, desc, authh, aarg, aref,
			    offerh, answerh, progrh, estabh, infoh, referh,
			    closeh, arg);
	if (err)
		return err;

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

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

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

		if (err)
			goto out;
	}

	sess->owner = true;

	err = sip_dialog_alloc(&sess->dlg, to_uri, to_uri, from_name,
			       from_uri, routev, routec);
	if (err)
		goto out;

	hash_append(sock->ht_sess,
		    hash_joaat_str(sip_dialog_callid(sess->dlg)),
		    &sess->he, sess);

	err = invite(sess);
	if (err)
		goto out;

 out:
	if (err)
		mem_deref(sess);
	else
		*sessp = sess;

	return err;
}
Esempio n. 8
0
static struct device *find_device(const char *device)
{
	return list_ledata(hash_lookup(ht_device, hash_joaat_str(device),
				       list_apply_handler, (void *)device));
}
Esempio n. 9
0
int sipevent_accept(struct sipnot **notp, struct sipevent_sock *sock,
		    const struct sip_msg *msg, struct sip_dialog *dlg,
		    const struct sipevent_event *event,
		    uint16_t scode, const char *reason, uint32_t expires_min,
		    uint32_t expires_dfl, uint32_t expires_max,
		    const char *cuser, const char *ctype,
		    sip_auth_h *authh, void *aarg, bool aref,
		    sipnot_close_h *closeh, void *arg, const char *fmt, ...)
{
	struct sipnot *not;
	uint32_t expires;
	int err;

	if (!notp || !sock || !msg || !scode || !reason || !expires_dfl ||
	    !expires_max || !cuser || !ctype || expires_dfl < expires_min)
		return EINVAL;

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

	if (!pl_strcmp(&msg->met, "REFER")) {

		err = str_dup(&not->event, "refer");
		if (err)
			goto out;

		err = re_sdprintf(&not->id, "%u", msg->cseq.num);
		if (err)
			goto out;
	}
	else {
		if (!event) {
			err = EINVAL;
			goto out;
		}

		err = pl_strdup(&not->event, &event->event);
		if (err)
			goto out;

		if (pl_isset(&event->id)) {

			err = pl_strdup(&not->id, &event->id);
			if (err)
				goto out;
		}
	}

	if (dlg) {
		not->dlg = mem_ref(dlg);
	}
	else {
		err = sip_dialog_accept(&not->dlg, msg);
		if (err)
			goto out;
	}

	hash_append(sock->ht_not,
		    hash_joaat_str(sip_dialog_callid(not->dlg)),
		    &not->he, not);

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

	err = str_dup(&not->cuser, cuser);
	if (err)
		goto out;

	err = str_dup(&not->ctype, ctype);
	if (err)
		goto out;

	if (fmt) {
		va_list ap;

		va_start(ap, fmt);
		err = re_vsdprintf(&not->hdrs, fmt, ap);
		va_end(ap);
		if (err)
			goto out;
	}

	not->expires_min = expires_min;
	not->expires_dfl = expires_dfl;
	not->expires_max = expires_max;
	not->substate = SIPEVENT_PENDING;
	not->sock   = mem_ref(sock);
	not->sip    = mem_ref(sock->sip);
	not->closeh = closeh ? closeh : internal_close_handler;
	not->arg    = arg;

	if (pl_isset(&msg->expires))
		expires = pl_u32(&msg->expires);
	else
		expires = not->expires_dfl;

	sipnot_refresh(not, expires);

	err = sipnot_reply(not, msg, scode, reason);
	if (err)
		goto out;

	not->subscribed = true;

 out:
	if (err)
		mem_deref(not);
	else
		*notp = not;

	return err;
}