示例#1
0
static void retransmit_handler(void *arg)
{
	struct sip_ctrans *ct = arg;
	uint32_t timeout;
	int err;

	ct->txc++;

	switch (ct->state) {

	case TRYING:
		timeout = MIN(SIP_T1<<ct->txc, SIP_T2);
		break;

	case CALLING:
		timeout = SIP_T1<<ct->txc;
		break;

	case PROCEEDING:
		timeout = SIP_T2;
		break;

	default:
		return;
	}

	tmr_start(&ct->tmre, timeout, retransmit_handler, ct);

	err = sip_transp_send(&ct->qent, ct->sip, NULL, ct->tp, &ct->dst,
			      ct->mb, transport_handler, ct);
	if (err) {
		terminate(ct, err);
		mem_deref(ct);
	}
}
示例#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;
}
示例#3
0
/**
 * Send a SIP message
 *
 * @param sip  SIP stack instance
 * @param sock Optional socket to send from
 * @param tp   SIP transport
 * @param dst  Destination network address
 * @param mb   Buffer containing SIP message
 *
 * @return 0 if success, otherwise errorcode
 */
int sip_send(struct sip *sip, void *sock, enum sip_transp tp,
	     const struct sa *dst, struct mbuf *mb)
{
	return sip_transp_send(NULL, sip, sock, tp, dst, mb, NULL, NULL);
}