Пример #1
0
/* When done, this function also has the job to unref the dialog as removed
 * from timer list. This must be done in all cases!!
 */
void dlg_ontimeout( struct dlg_tl *tl)
{
	struct dlg_cell *dlg;
	int new_state;
	int old_state;
	int unref;

	dlg = get_dlg_tl_payload(tl);

	LM_DBG("byeontimeout ? %d , state = %d\n",dlg->flags,dlg->state);

	if ( (dlg->flags&DLG_FLAG_BYEONTIMEOUT) &&
	(dlg->state==DLG_STATE_CONFIRMED_NA || dlg->state==DLG_STATE_CONFIRMED)) {

		init_dlg_term_reason(dlg,"Lifetime Timeout",sizeof("Lifetime Timeout")-1);

		/* we just send the BYEs in both directions */
		dlg_end_dlg( dlg, NULL);
		/* dialog is no longer refed by timer; from now one it is refed
		   by the send_bye functions */
		unref_dlg( dlg, 1);
		/* is not 100% sure, but do it */
		if_update_stat( dlg_enable_stats, expired_dlgs, 1);
		return ;
	}

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

	if (new_state==DLG_STATE_DELETED && old_state!=DLG_STATE_DELETED) {
		LM_DBG("timeout for dlg with CallID '%.*s' and tags '%.*s' '%.*s'\n",
			dlg->callid.len, dlg->callid.s,
			dlg->legs[DLG_CALLER_LEG].tag.len,
			dlg->legs[DLG_CALLER_LEG].tag.s,
			dlg->legs[callee_idx(dlg)].tag.len,
			ZSW(dlg->legs[callee_idx(dlg)].tag.s));

		/*destroy linkers */
		destroy_linkers(dlg->profile_links);
		dlg->profile_links = NULL;

		/* dialog timeout */
		run_dlg_callbacks( DLGCB_EXPIRED, dlg, 0, DLG_DIR_NONE, 0);

		/* delete the dialog from DB */
		if (should_remove_dlg_db())
			remove_dialog_from_db(dlg);

		unref_dlg(dlg, unref + 1 /*timer list*/);

		if_update_stat( dlg_enable_stats, expired_dlgs, 1);
		if_update_stat( dlg_enable_stats, active_dlgs, -1);
	} else {
		unref_dlg(dlg, 1 /*just timer list*/);
	}

	return;
}
Пример #2
0
void dlg_ping_routine(unsigned int ticks , void * attr)
{
	struct dlg_ping_list *expired,*it,*curr;
	struct dlg_cell *dlg;

	expired = get_timeout_dlgs();

	it = expired;
	while (it) {
		dlg = it->dlg;
		LM_DBG("dialog %p has expired\n",dlg);
		curr = it->next;
		shm_free(it);
		dlg->pl = 0;
		it = curr;

		/* no longer reffed in list */
		unref_dlg(dlg,1);
		/* dlg is still reffed in TM callback. deletion from memory
		 * will happen only on 408 timeout */

		/* FIXME - maybe better not to send BYE both ways as we know for sure one
		 * end in down . */
		dlg_end_dlg(dlg,0);
	}

	/* ping_timer->first now contains all active dialogs */
	it = ping_timer->first;
	while (it) {
		dlg = it->dlg;

		/* do not ping ended dialogs */
		if (dlg->state != DLG_STATE_DELETED) {
			if (dlg->flags & DLG_FLAG_PING_CALLER) {
				ref_dlg(dlg,1);
				if (send_leg_msg(dlg,&options_str,callee_idx(dlg),
				DLG_CALLER_LEG,0,0,reply_from_caller,dlg,unref_dlg_cb) < 0) {
					LM_ERR("failed to ping caller\n");
					unref_dlg(dlg,1);
				}
			}

			if (dlg->flags & DLG_FLAG_PING_CALLEE) {
				ref_dlg(dlg,1);
				if (send_leg_msg(dlg,&options_str,DLG_CALLER_LEG,
				callee_idx(dlg),0,0,reply_from_callee,dlg,unref_dlg_cb) < 0) {
					LM_ERR("failed to ping callee\n");
					unref_dlg(dlg,1);
				}
			}
		}
		it = it->next;
	}
}
Пример #3
0
int terminate_dlg(unsigned int h_entry, unsigned int h_id,str *reason)
{
	struct dlg_cell * dlg = NULL;
	int ret = 0;

	dlg = lookup_dlg(h_entry, h_id);

	if(!dlg)
		return 0;

	init_dlg_term_reason(dlg,reason->s,reason->len);

	if ( dlg_end_dlg( dlg, 0) ) {
		LM_ERR("Failed to end dialog");
		ret = -1;
	}

	unref_dlg(dlg, 1);
	return ret;
}
Пример #4
0
/*parameters from MI: h_entry, h_id of the requested dialog*/
struct mi_root * mi_terminate_dlg(struct mi_root *cmd_tree, void *param ){

	struct mi_node* node;
	unsigned int h_entry, h_id;
	struct dlg_cell * dlg = NULL;
	str *mi_extra_hdrs = NULL;
	int status, msg_len;
	char *msg;


	if( d_table ==NULL)
		goto end;

	node = cmd_tree->node.kids;
	h_entry = h_id = 0;

	if (node==NULL || node->next==NULL)
		return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);

	if (!node->value.s|| !node->value.len|| strno2int(&node->value,&h_entry)<0)
		goto error;

	node = node->next;
	if ( !node->value.s || !node->value.len || strno2int(&node->value,&h_id)<0)
		goto error;

	if (node->next) {
		node = node->next;
		if (node->value.len && node->value.s)
			mi_extra_hdrs = &node->value;
	}

	LM_DBG("h_entry %u h_id %u\n", h_entry, h_id);

	dlg = lookup_dlg(h_entry, h_id);

	/* lookup_dlg has incremented the reference count !! */

	if(dlg){
		init_dlg_term_reason(dlg,"MI Termination",sizeof("MI Termination")-1);

		if ( dlg_end_dlg( dlg, mi_extra_hdrs) ) {
			status = 500;
			msg = MI_DLG_OPERATION_ERR;
			msg_len = MI_DLG_OPERATION_ERR_LEN;
		} else {
			status = 200;
			msg = MI_OK_S;
			msg_len = MI_OK_LEN;
		}

		unref_dlg(dlg, 1);

		return init_mi_tree(status, msg, msg_len);
	}

end:
	return init_mi_tree(404, MI_DIALOG_NOT_FOUND, MI_DIALOG_NOT_FOUND_LEN);
	
error:
	return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);

}