Ejemplo n.º 1
0
/* send keep-alive
 * dlg - pointer to a struct dlg_cell
 * dir - direction: the request will be sent to:
 * 		DLG_CALLER_LEG (0): caller
 * 		DLG_CALLEE_LEG (1): callee
 */
int dlg_send_ka(dlg_cell_t *dlg, int dir, str *hdrs)
{
	uac_req_t uac_r;
	dlg_t* di;
	str met = {"OPTIONS", 7};
	int result;
	dlg_iuid_t *iuid = NULL;

	/* do not send KA request for non-confirmed dialogs (not supported) */
	if (dlg->state != DLG_STATE_CONFIRMED) {
		LM_DBG("skipping non-confirmed dialogs\n");
		return 0;
	}

	/* build tm dlg by direction */
	if ((di = build_dlg_t(dlg, dir)) == 0){
		LM_ERR("failed to create dlg_t\n");
		goto err;
	}

	/* tm increases cseq value, decrease it no to make it invalid
	 * - dialog is ended on timeout (408) or C/L does not exist (481) */
	if(di->loc_seq.value>1)
		di->loc_seq.value -= 2;
	else
		di->loc_seq.value -= 1;

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

	iuid = dlg_get_iuid_shm_clone(dlg);
	if(iuid==NULL)
	{
		LM_ERR("failed to create dialog unique id clone\n");
		goto err;
	}

	memset(&uac_r,'\0', sizeof(uac_req_t));
	set_uac_req(&uac_r, &met, hdrs, NULL, di, TMCB_LOCAL_COMPLETED,
				dlg_ka_cb, (void*)iuid);
	result = d_tmb.t_request_within(&uac_r);

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

	free_tm_dlg(di);

	LM_DBG("keep-alive sent to %s\n", (dir==0)?"caller":"callee");
	return 0;

err:
	if(di)
		free_tm_dlg(di);
	return -1;
}
Ejemplo n.º 2
0
/* 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;
}
Ejemplo n.º 3
0
static int dlg_refer_callee(dlg_transfer_ctx_t *dtc)
{
	/*verify direction*/
	dlg_t* dialog_info = NULL;
	str met = {"REFER", 5};
	int result;
	str hdrs;
	struct dlg_cell *dlg;
	uac_req_t uac_r;

	dlg = dtc->dlg;

	if ((dialog_info = build_dlg_t(dlg, DLG_CALLEE_LEG)) == 0){
		LM_ERR("failed to create dlg_t\n");
		goto error;
	}

	hdrs.len = 23 + 2*CRLF_LEN + dlg_bridge_controller.len
		+ dtc->to.len + dlg_bridge_ref_hdrs.len;
	LM_DBG("sending REFER [%d] <%.*s>\n", hdrs.len, dtc->to.len, dtc->to.s);
	hdrs.s = (char*)pkg_malloc(hdrs.len*sizeof(char));
	if(hdrs.s == NULL)
		goto error;
	memcpy(hdrs.s, "Referred-By: ", 13);
	memcpy(hdrs.s+13, dlg_bridge_controller.s, dlg_bridge_controller.len);
	memcpy(hdrs.s+13+dlg_bridge_controller.len, CRLF, CRLF_LEN);
	memcpy(hdrs.s+13+dlg_bridge_controller.len+CRLF_LEN, "Refer-To: ", 10);
	memcpy(hdrs.s+23+dlg_bridge_controller.len+CRLF_LEN, dtc->to.s,
			dtc->to.len);
	memcpy(hdrs.s+23+dlg_bridge_controller.len+CRLF_LEN+dtc->to.len,
			CRLF, CRLF_LEN);
	memcpy(hdrs.s+23+dlg_bridge_controller.len+CRLF_LEN+dtc->to.len+CRLF_LEN,
			dlg_bridge_ref_hdrs.s, dlg_bridge_ref_hdrs.len);

	set_uac_req(&uac_r, &met, &hdrs, NULL, dialog_info, TMCB_LOCAL_COMPLETED,
				dlg_refer_tm_callback, (void*)dtc);
	result = d_tmb.t_request_within(&uac_r);

	pkg_free(hdrs.s);
	if(result < 0) {
		LM_ERR("failed to send the REFER request\n");
		/* todo: clean-up dtc */
		goto error;
	}

	free_tm_dlg(dialog_info);

	LM_DBG("REFER sent\n");
	return 0;

error:
	if(dialog_info)
		free_tm_dlg(dialog_info);
	return -1;
}
Ejemplo n.º 4
0
void dlg_refer_tm_callback(struct cell *t, int type, struct tmcb_params *ps)
{
	dlg_transfer_ctx_t *dtc = NULL;
	dlg_t* dialog_info = NULL;
	str met = {"BYE", 3};
	int result;
	struct dlg_cell *dlg;
	uac_req_t uac_r;

	if(ps->param==NULL || *ps->param==0)
	{
		LM_DBG("message id not received\n");
		return;
	}
	dtc = *((dlg_transfer_ctx_t**)ps->param);
	if(dtc==NULL)
		return;
	LM_DBG("REFER completed with status %d\n", ps->code);

	/* we send the BYE anyhow */
	dlg = dtc->dlg;
	if ((dialog_info = build_dlg_t(dlg, DLG_CALLEE_LEG)) == 0){
		LM_ERR("failed to create dlg_t\n");
		goto error;
	}

	/* after REFER, the CSeq must be increased */
	dialog_info->loc_seq.value++;

	set_uac_req(&uac_r, &met, NULL, NULL, dialog_info, 0, NULL, NULL);
	result = d_tmb.t_request_within(&uac_r);

	if(result < 0) {
		LM_ERR("failed to send the REFER request\n");
		/* todo: clean-up dtc */
		goto error;
	}

	free_tm_dlg(dialog_info);
	dlg_transfer_ctx_free(dtc);

	LM_DBG("BYE sent\n");
	return;

error:
	dlg_transfer_ctx_free(dtc);
	if(dialog_info)
		free_tm_dlg(dialog_info);
	return;

}
Ejemplo n.º 5
0
/* cell- pointer to a struct dlg_cell
 * dir- direction: the request will be sent to:
 * 		DLG_CALLER_LEG (0): caller
 * 		DLG_CALLEE_LEG (1): callee
 */
static inline int send_bye(struct dlg_cell * cell, int dir, str *hdrs)
{
	uac_req_t uac_r;
	dlg_t* dialog_info;
	str met = {"BYE", 3};
	int result;
	dlg_iuid_t *iuid = NULL;

	/* do not send BYE request for non-confirmed dialogs (not supported) */
	if (cell->state != DLG_STATE_CONFIRMED_NA && cell->state != DLG_STATE_CONFIRMED) {
		LM_ERR("terminating non-confirmed dialogs not supported\n");
		return -1;
	}

	/*verify direction*/

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

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

	iuid = dlg_get_iuid_shm_clone(cell);
	if(iuid==NULL)
	{
		LM_ERR("failed to create dialog unique id clone\n");
		goto err;
	}

	memset(&uac_r,'\0', sizeof(uac_req_t));
	set_uac_req(&uac_r, &met, hdrs, NULL, dialog_info, TMCB_LOCAL_COMPLETED,
				bye_reply_cb, (void*)iuid);
	result = d_tmb.t_request_within(&uac_r);

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

	free_tm_dlg(dialog_info);

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

err:
	if(dialog_info)
		free_tm_dlg(dialog_info);
	return -1;
}
Ejemplo n.º 6
0
/* 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)
{
	dlg_t* dialog_info;
	struct dlg_cell *old_cell;
	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);

	ref_dlg(cell, 1);

	old_cell = current_dlg_pointer;
	current_dlg_pointer = cell;

	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*/

	current_dlg_pointer = old_cell;

	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;
}