Ejemplo n.º 1
0
/*!
 * \brief add dlg structure to tm callbacks to wait for negative ACK
 * \param t current transaction
 * \param dlg current dialog
 * \return 0 on success, -1 on failure
 */
int dlg_set_tm_waitack(tm_cell_t *t, dlg_cell_t *dlg)
{
	dlg_iuid_t *iuid = NULL;
	if(t==NULL)
		return -1;

	LM_DBG("registering TMCB to wait for negative ACK\n");
	iuid = dlg_get_iuid_shm_clone(dlg);
	if(iuid==NULL)
	{
		LM_ERR("failed to create dialog unique id clone\n");
		goto error;
	}
	dlg_ref(dlg, 1);
	if ( d_tmb.register_tmcb( NULL, t,
			TMCB_DESTROY,
			dlg_ontdestroy, (void*)iuid, dlg_iuid_sfree)<0 ) {
		LM_ERR("failed to register TMCB to wait for negative ACK\n");
		dlg_unref(dlg, 1);
		goto error;
	}

	return 0;
error:
	dlg_iuid_sfree(iuid);
	return -1;
}
Ejemplo n.º 2
0
/*!
 * \brief add dlg structure to tm callbacks
 * \param t current transaction
 * \param req current sip request
 * \param dlg current dialog
 * \param smode if the sip request was spiraled
 * \return 0 on success, -1 on failure
 */
int dlg_set_tm_callbacks(tm_cell_t *t, sip_msg_t *req, dlg_cell_t *dlg,
		int smode)
{
	dlg_iuid_t *iuid = NULL;
	if(t==NULL)
		return -1;

	if(smode==0) {
		iuid = dlg_get_iuid_shm_clone(dlg);
		if(iuid==NULL)
		{
			LM_ERR("failed to create dialog unique id clone\n");
			goto error;
		}
		if ( d_tmb.register_tmcb( req, t,
				TMCB_RESPONSE_IN|TMCB_RESPONSE_READY|TMCB_RESPONSE_FWDED|TMCB_ON_FAILURE,
				dlg_onreply, (void*)iuid, dlg_iuid_sfree)<0 ) {
			LM_ERR("failed to register TMCB\n");
			goto error;
		}
	}

	dlg->dflags |= DLG_FLAG_TM;

	return 0;
error:
	dlg_iuid_sfree(iuid);
	return -1;
}
Ejemplo n.º 3
0
/* callback function to handle responses to the keep-alive request */
void dlg_ka_cb(struct cell* t, int type, struct tmcb_params* ps){

	dlg_cell_t* dlg;
	dlg_iuid_t *iuid = NULL;

	if(ps->param == NULL || *ps->param == NULL) {
		LM_ERR("invalid parameter\n");
		return;
	}

	if(ps->code < 200) {
		LM_DBG("receiving a provisional reply\n");
		return;
	}

	LM_DBG("receiving a final reply %d\n",ps->code);

	iuid = (dlg_iuid_t*)(*ps->param);
	dlg = dlg_get_by_iuid(iuid);
	if(dlg==0) {
		dlg_iuid_sfree(iuid);
		return;
	}

	if(ps->code==408 || ps->code==481) {
		if(update_dlg_timer(&dlg->tl, 10)<0) {
			LM_ERR("failed to update dialog lifetime\n");
			goto done;
		}
		dlg->lifetime = 10;
		dlg->dflags |= DLG_FLAG_CHANGED;
	}

done:
	dlg_unref(dlg, 1);
	dlg_iuid_sfree(iuid);
}
Ejemplo n.º 4
0
/* callback function to handle responses to the BYE request */
void bye_reply_cb(struct cell* t, int type, struct tmcb_params* ps){

	struct dlg_cell* dlg;
	int event, old_state, new_state, unref, ret;
	dlg_iuid_t *iuid = NULL;

	if(ps->param == NULL || *ps->param == NULL){
		LM_ERR("invalid parameter\n");
		return;
	}

	if(ps->code < 200){
		LM_DBG("receiving a provisional reply\n");
		return;
	}

	LM_DBG("receiving a final reply %d\n",ps->code);

	iuid = (dlg_iuid_t*)(*ps->param);
	dlg = dlg_get_by_iuid(iuid);
	if(dlg==0)
		return;

	event = DLG_EVENT_REQBYE;
	next_state_dlg(dlg, event, &old_state, &new_state, &unref);

	if(new_state == DLG_STATE_DELETED && old_state != DLG_STATE_DELETED){

		LM_DBG("removing dialog with h_entry %u and h_id %u\n", 
			dlg->h_entry, dlg->h_id);

		/* remove from timer */
		ret = remove_dialog_timer(&dlg->tl);
		if (ret < 0) {
			LM_CRIT("unable to unlink the timer on dlg %p [%u:%u] "
				"with clid '%.*s' and tags '%.*s' '%.*s'\n",
				dlg, dlg->h_entry, dlg->h_id,
				dlg->callid.len, dlg->callid.s,
				dlg->tag[DLG_CALLER_LEG].len, dlg->tag[DLG_CALLER_LEG].s,
				dlg->tag[DLG_CALLEE_LEG].len, dlg->tag[DLG_CALLEE_LEG].s);
		} else if (ret > 0) {
			LM_WARN("inconsitent dlg timer data on dlg %p [%u:%u] "
				"with clid '%.*s' and tags '%.*s' '%.*s'\n",
				dlg, dlg->h_entry, dlg->h_id,
				dlg->callid.len, dlg->callid.s,
				dlg->tag[DLG_CALLER_LEG].len, dlg->tag[DLG_CALLER_LEG].s,
				dlg->tag[DLG_CALLEE_LEG].len, dlg->tag[DLG_CALLEE_LEG].s);
		} else {
			unref++;
		}
		/* dialog terminated (BYE) */
		run_dlg_callbacks( DLGCB_TERMINATED, dlg, ps->req, ps->rpl, DLG_DIR_NONE, 0);

		LM_DBG("first final reply\n");
		/* derefering the dialog */
		dlg_unref(dlg, unref+1);

		if_update_stat( dlg_enable_stats, active_dlgs, -1);
	}

	if(new_state == DLG_STATE_DELETED && old_state == DLG_STATE_DELETED ) {
		/* trash the dialog from DB and memory */
		LM_DBG("second final reply\n");
		/* delete the dialog from DB */
		if (dlg_db_mode)
			remove_dialog_from_db(dlg);
		/* force delete from mem */
		dlg_unref(dlg, 1);
	}
	dlg_iuid_sfree(iuid);
}