コード例 #1
0
ファイル: dlg_req_within.c プロジェクト: GeorgeShaw/opensips
int send_leg_msg(struct dlg_cell *dlg,str *method,int src_leg,int dst_leg,
		str *hdrs,str *body,dlg_request_callback func,void *param,dlg_release_func release)
{
	context_p old_ctx;
	dlg_t* dialog_info;
	int result;
	unsigned int method_type;

	if (parse_method(method->s,method->s+method->len,&method_type) == 0)
	{
		LM_ERR("Failed to parse method - [%.*s]\n",method->len,method->s);
		return -1;
	}

	if (method_type == METHOD_INVITE && (body == NULL || body->s == NULL ||
				body->len == 0))
	{
		LM_ERR("Cannot send INVITE without SDP body\n");
		return -1;
	}

	if ((dialog_info = build_dialog_info(dlg, dst_leg, src_leg)) == 0)
	{
		LM_ERR("failed to create dlg_t\n");
		return -1;
	}

	LM_DBG("sending [%.*s] to %s (%d)\n",method->len,method->s,
		(dst_leg==DLG_CALLER_LEG)?"caller":"callee", dst_leg);

	/* set new processing context */
	if (push_new_processing_context( dlg, &old_ctx, NULL)!=0)
		return -1;

	dialog_info->T_flags=T_NO_AUTOACK_FLAG;

	result = d_tmb.t_request_within
		(method,         /* method*/
		hdrs,		    /* extra headers*/
		body,          /* body*/
		dialog_info,   /* dialog structure*/
		func,  /* callback function*/
		param,   /* callback parameter*/
		release);         /* release function*/

	/* reset the processing contect */
	current_processing_ctx = old_ctx;

	if(result < 0)
	{
		LM_ERR("failed to send the in-dialog request\n");
		free_tm_dlg(dialog_info);
		return -1;
	}

	free_tm_dlg(dialog_info);
	return 0;
}
コード例 #2
0
ファイル: dlg_req_within.c プロジェクト: Deni90/opensips
/* cell- pointer to a struct dlg_cell
 * leg - a dialog leg to be BYE'ed :
 *     = 0: caller leg
 *     > 0: callee legs
 */
static inline int send_leg_bye(struct dlg_cell *cell, int dst_leg, int src_leg,
														str *extra_hdrs)
{
	context_p old_ctx;
	context_p *new_ctx;
	dlg_t* dialog_info;
	str met = {"BYE", 3};
	int result;

	if ((dialog_info = build_dlg_t(cell, dst_leg, src_leg)) == 0){
		LM_ERR("failed to create dlg_t\n");
		goto err;
	}

	LM_DBG("sending BYE to %s (%d)\n",
		(dst_leg==DLG_CALLER_LEG)?"caller":"callee", dst_leg);

	/* set new processing context */
	if (push_new_processing_context( cell, &old_ctx, &new_ctx, NULL)!=0)
		goto err;

	ctx_lastdstleg_set(dst_leg);

	ref_dlg(cell, 1);

	result = d_tmb.t_request_within
		(&met,         /* method*/
		extra_hdrs,    /* extra headers*/
		NULL,          /* body*/
		dialog_info,   /* dialog structure*/
		bye_reply_cb,  /* callback function*/
		(void*)cell,   /* callback parameter*/
		NULL);         /* release function*/

	/* reset the processing contect */
	if (current_processing_ctx == NULL)
		*new_ctx = NULL;
	else
		context_destroy(CONTEXT_GLOBAL, *new_ctx);
	current_processing_ctx = old_ctx;

	if(result < 0){
		LM_ERR("failed to send the BYE request\n");
		goto err1;
	}

	free_tm_dlg(dialog_info);

	LM_DBG("BYE sent to %s\n", (dst_leg==DLG_CALLER_LEG)?"caller":"callee");
	return 0;

err1:
	unref_dlg(cell, 1);
err:
	return -1;
}
コード例 #3
0
ファイル: dlg_req_within.c プロジェクト: GeorgeShaw/opensips
static void dual_bye_event(struct dlg_cell* dlg, struct sip_msg *req, int extra_unref)
{
	int event, old_state, new_state, unref, ret;
	struct sip_msg *fake_msg=NULL;
	context_p old_ctx;

	event = DLG_EVENT_REQBYE;
	next_state_dlg(dlg, event, DLG_DIR_DOWNSTREAM, &old_state, &new_state,
			&unref, dlg->legs_no[DLG_LEG_200OK], 0);
	unref += extra_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);

		/*destroy linkers */
		dlg_lock_dlg(dlg);
		destroy_linkers(dlg->profile_links, 0);
		dlg->profile_links = NULL;
		dlg_unlock_dlg(dlg);

		/* remove from timer */
		ret = remove_dlg_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_leg_print_info( dlg, DLG_CALLER_LEG, tag),
				dlg_leg_print_info( dlg, callee_idx(dlg), tag));
		} else if (ret > 0) {
			LM_DBG("dlg already expired (not in timer list) %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_leg_print_info( dlg, DLG_CALLER_LEG, tag),
				dlg_leg_print_info( dlg, callee_idx(dlg), tag));
		} else {
			/* successfully removed from timer list */
			unref++;
		}

		if (req==NULL) {
			/* set new msg & processing context */
			if (push_new_processing_context( dlg, &old_ctx, &fake_msg)==0) {
				/* dialog terminated (BYE) */
				run_dlg_callbacks( DLGCB_TERMINATED, dlg, fake_msg, DLG_DIR_NONE, 0);
				/* reset the processing contect */
				current_processing_ctx = old_ctx;
			} /* no CB run in case of failure FIXME */
		} else {
			/* we should have the msg and context from upper levels */
			/* dialog terminated (BYE) */
			run_dlg_callbacks( DLGCB_TERMINATED, dlg, req, DLG_DIR_NONE, 0);
		}

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

		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 (should_remove_dlg_db())
			remove_dialog_from_db(dlg);
		/* force delete from mem */
		unref_dlg(dlg, unref);
	}
}