void pjsip_dlg_on_tsx_state( pjsip_dialog *dlg,
			     pjsip_transaction *tsx,
			     pjsip_event *e )
{
    unsigned i;

    PJ_LOG(5,(dlg->obj_name, "Transaction %s state changed to %s",
	      tsx->obj_name, pjsip_tsx_state_str(tsx->state)));
    pj_log_push_indent();

    /* Lock the dialog and increment session. */
    pjsip_dlg_inc_lock(dlg);

    /* Pass to dialog usages. */
    for (i=0; i<dlg->usage_cnt; ++i) {

	if (!dlg->usage[i]->on_tsx_state)
	    continue;

	(*dlg->usage[i]->on_tsx_state)(tsx, e);
    }


    /* It is possible that the transaction is terminated and this function
     * is called while we're calling on_tsx_state(). So only decrement
     * the tsx_count if we're still attached to the transaction.
     */
    if (tsx->state == PJSIP_TSX_STATE_TERMINATED &&
	tsx->mod_data[dlg->ua->id] == dlg)
    {
	pj_assert(dlg->tsx_count>0);
	--dlg->tsx_count;
	tsx->mod_data[dlg->ua->id] = NULL;
    }

    /* Unlock dialog and dec session, may destroy dialog. */
    pjsip_dlg_dec_lock(dlg);
    pj_log_pop_indent();
}
void pjsip_dlg_on_tsx_state( pjsip_dialog *dlg,
			     pjsip_transaction *tsx,
			     pjsip_event *e )
{
    unsigned i;

    PJ_LOG(5,(dlg->obj_name, "Transaction %s state changed to %s",
	      tsx->obj_name, pjsip_tsx_state_str(tsx->state)));
    pj_log_push_indent();

     
    pjsip_dlg_inc_lock(dlg);

     
    for (i=0; i<dlg->usage_cnt; ++i) {

	if (!dlg->usage[i]->on_tsx_state)
	    continue;

	(*dlg->usage[i]->on_tsx_state)(tsx, e);
    }


     
    if (tsx->state == PJSIP_TSX_STATE_TERMINATED &&
	tsx->mod_data[dlg->ua->id] == dlg)
    {
	pj_assert(dlg->tsx_count>0);
	--dlg->tsx_count;
	tsx->mod_data[dlg->ua->id] = NULL;
    }

     
    pjsip_dlg_dec_lock(dlg);
    pj_log_pop_indent();
}