Beispiel #1
0
/*
 * Decrease transport data reference, destroy it when the reference count
 * reaches zero.
 */
PJ_DEF(pj_status_t) pjsip_tx_data_dec_ref( pjsip_tx_data *tdata )
{
    pj_assert( pj_atomic_get(tdata->ref_cnt) > 0);
    if (pj_atomic_dec_and_get(tdata->ref_cnt) <= 0) {
	PJ_LOG(5,(tdata->obj_name, "Destroying txdata %s",
		  pjsip_tx_data_get_info(tdata)));
	pjsip_tpselector_dec_ref(&tdata->tp_sel);
#if defined(PJ_DEBUG) && PJ_DEBUG!=0
	pj_atomic_dec( tdata->mgr->tdata_counter );
#endif
	pj_atomic_destroy( tdata->ref_cnt );
	pj_lock_destroy( tdata->lock );
	pjsip_endpt_release_pool( tdata->mgr->endpt, tdata->pool );
	return PJSIP_EBUFDESTROYED;
    } else {
	return PJ_SUCCESS;
    }
}
Beispiel #2
0
PJ_DEF(pj_status_t) pjsip_regc_send(pjsip_regc *regc, pjsip_tx_data *tdata)
{
    pj_status_t status;
    pjsip_cseq_hdr *cseq_hdr;
    pjsip_expires_hdr *expires_hdr;
    pj_uint32_t cseq;

    pj_atomic_inc(regc->busy_ctr);
    pj_lock_acquire(regc->lock);

    /* Make sure we don't have pending transaction. */
    if (regc->has_tsx) {
	PJ_LOG(4,(THIS_FILE, "Unable to send request, regc has another "
			     "transaction pending"));
	pjsip_tx_data_dec_ref( tdata );
	pj_lock_release(regc->lock);
	pj_atomic_dec(regc->busy_ctr);
	return PJSIP_EBUSY;
    }

    pj_assert(regc->current_op == REGC_IDLE);

    /* Invalidate message buffer. */
    pjsip_tx_data_invalidate_msg(tdata);

    /* Increment CSeq */
    cseq = ++regc->cseq_hdr->cseq;
    cseq_hdr = (pjsip_cseq_hdr*)
	       pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ, NULL);
    cseq_hdr->cseq = cseq;

    /* Find Expires header */
    expires_hdr = (pjsip_expires_hdr*)
		  pjsip_msg_find_hdr(tdata->msg, PJSIP_H_EXPIRES, NULL);

    /* Bind to transport selector */
    pjsip_tx_data_set_transport(tdata, &regc->tp_sel);

    regc->has_tsx = PJ_TRUE;

    /* Set current operation based on the value of Expires header */
    if (expires_hdr && expires_hdr->ivalue==0)
	regc->current_op = REGC_UNREGISTERING;
    else
	regc->current_op = REGC_REGISTERING;

    /* Prevent deletion of tdata, e.g: when something wrong in sending,
     * we need tdata to retrieve the transport.
     */
    pjsip_tx_data_add_ref(tdata);

    /* If via_addr is set, use this address for the Via header. */
    if (regc->via_addr.host.slen > 0) {
        tdata->via_addr = regc->via_addr;
        tdata->via_tp = regc->via_tp;
    }

    /* Need to unlock the regc temporarily while sending the message to
     * prevent deadlock (https://trac.pjsip.org/repos/ticket/1247).
     * It should be safe to do this since the regc's refcount has been
     * incremented.
     */
    pj_lock_release(regc->lock);

    /* Now send the message */
    status = pjsip_endpt_send_request(regc->endpt, tdata, REGC_TSX_TIMEOUT,
				      regc, &regc_tsx_callback);
    if (status!=PJ_SUCCESS) {
	PJ_LOG(4,(THIS_FILE, "Error sending request, status=%d", status));
    }

    /* Reacquire the lock */
    pj_lock_acquire(regc->lock);

    /* Get last transport used and add reference to it */
    if (tdata->tp_info.transport != regc->last_transport &&
	status==PJ_SUCCESS)
    {
	if (regc->last_transport) {
	    pjsip_transport_dec_ref(regc->last_transport);
	    regc->last_transport = NULL;
	}

	if (tdata->tp_info.transport) {
	    regc->last_transport = tdata->tp_info.transport;
	    pjsip_transport_add_ref(regc->last_transport);
	}
    }

    /* Release tdata */
    pjsip_tx_data_dec_ref(tdata);

    pj_lock_release(regc->lock);

    /* Delete the record if user destroy regc during the callback. */
    if (pj_atomic_dec_and_get(regc->busy_ctr)==0 && regc->_delete_flag) {
	pjsip_regc_destroy(regc);
    }

    return status;
}
Beispiel #3
0
    //
    // Decrement.
    //
    void dec()
    {
	pj_atomic_dec(var_);
    }
Beispiel #4
0
PJ_DEF(pj_status_t) pjsip_regc_send(pjsip_regc *regc, pjsip_tx_data *tdata)
{
    pj_status_t status;
    pjsip_cseq_hdr *cseq_hdr;
    pjsip_expires_hdr *expires_hdr;
    pj_uint32_t cseq;

    pj_atomic_inc(regc->busy_ctr);
    pj_lock_acquire(regc->lock);

    /* Make sure we don't have pending transaction. */
    if (regc->has_tsx) {
	PJ_LOG(4,(THIS_FILE, "Unable to send request, regc has another "
			     "transaction pending"));
	pjsip_tx_data_dec_ref( tdata );
	pj_lock_release(regc->lock);
	pj_atomic_dec(regc->busy_ctr);
	return PJSIP_EBUSY;
    }

    pj_assert(regc->current_op == REGC_IDLE);

    /* Invalidate message buffer. */
    pjsip_tx_data_invalidate_msg(tdata);

    /* Increment CSeq */
    cseq = ++regc->cseq_hdr->cseq;
    cseq_hdr = (pjsip_cseq_hdr*)
	       pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ, NULL);
    cseq_hdr->cseq = cseq;

    /* Find Expires header */
    expires_hdr = (pjsip_expires_hdr*)
		  pjsip_msg_find_hdr(tdata->msg, PJSIP_H_EXPIRES, NULL);

    /* Bind to transport selector */
    pjsip_tx_data_set_transport(tdata, &regc->tp_sel);

    regc->has_tsx = PJ_TRUE;

    /* Set current operation based on the value of Expires header */
    if (expires_hdr && expires_hdr->ivalue==0)
	regc->current_op = REGC_UNREGISTERING;
    else
	regc->current_op = REGC_REGISTERING;

    status = pjsip_endpt_send_request(regc->endpt, tdata, REGC_TSX_TIMEOUT,
				      regc, &tsx_callback);
    if (status!=PJ_SUCCESS) {
	PJ_LOG(4,(THIS_FILE, "Error sending request, status=%d", status));
    }

    pj_lock_release(regc->lock);

    /* Delete the record if user destroy regc during the callback. */
    if (pj_atomic_dec_and_get(regc->busy_ctr)==0 && regc->_delete_flag) {
	pjsip_regc_destroy(regc);
    }

    return status;
}