Example #1
0
static int w_dlg_bye(struct sip_msg *msg, char *side, char *s2)
{
	dlg_cell_t *dlg = NULL;
	int n;

	dlg = dlg_get_ctx_dialog();
	if(dlg==NULL)
		return -1;
	
	n = (int)(long)side;
	if(n==1)
	{
		if(dlg_bye(dlg, NULL, DLG_CALLER_LEG)!=0)
			goto error;
		goto done;
	} else if(n==2) {
		if(dlg_bye(dlg, NULL, DLG_CALLEE_LEG)!=0)
			goto error;
		goto done;
	} else {
		if(dlg_bye_all(dlg, NULL)!=0)
			goto error;
		goto done;
	}

done:
	dlg_release(dlg);
	return 1;

error:
	dlg_release(dlg);
	return -1;
}
Example #2
0
/* side =
 * 0: caller
 * 1: callee
 * 2: all
 */
int dlg_terminate(struct dlg_cell *dlg, struct sip_msg *msg, str *reason, int side, str *extra_hdrs) {

    struct cell* t;
    str default_reason = {"call failed", 11};
    int cfg_cmd = 0;
    str default_extra_headers = {0,0};

    if (!dlg) {
        LM_ERR("calling end_dialog with NULL pointer dlg\n");
        return -1;
    }

    if (!extra_hdrs)
        extra_hdrs = &default_extra_headers;


    if (msg) {
        //assume called from cfg command -> dlg_terminate, as opposed to internal API or mi interface
        cfg_cmd = 1;
    }

    if (!reason || reason->len <= 0 || !reason->s) {
        reason = &default_reason;
    }

    if (dlg->state != DLG_STATE_CONFIRMED) {
        if (side != 2) {
            LM_ERR("can't terminate only 1 side of an early dialog\n");
            return -1;
        }
        if (dlg->transaction) {
            LM_DBG("terminating early dialog with %d outbound forks\n",
                    dlg->transaction->nr_of_outgoings);

            t = dlg->transaction;

            if (t && t!=(void*) -1  && t->uas.request) {
                if (t->method.len!=6 || t->method.s[0]!='I' || t->method.s[1]!='N' || t->method.s[2]!='V')
		{
			//well this is the transaction of a subsequent request within the dialog
			//and the dialog is not confirmed yet, so its a PRACK or an UPDATE
			//could also be an options, but the important thing is how am i going to get
			//the transaction of the invite, that is the one i have to cancel
			LM_WARN("this is not my transaction so where am i?\n");
                        return 1; //TODO - need to check why we got in here once before? this crashed on t_reply as t seemed invalid
		}

                //TODO: here we are assuming none of the CALLEE's have sent a 200, in
                //which case we would have to send an ACK, BYE
                //so right now - we are sending 488 to caller and CANCEL's to all CALLEEs

                LM_DBG("tearing down dialog in EARLY state - no clients responded > 199\n");
                if (cfg_cmd) {
                        d_tmb.t_reply(msg,488,reason->s);
                        d_tmb.t_release(msg);
                } else {
                        d_tmb.t_reply(t->uas.request,488,reason->s);
                        d_tmb.t_release(t->uas.request);
                }
            }
        } else {
            LM_WARN("can't terminate early dialog without a transaction\n");
            return -1;
        }
    } else {
        LM_DBG("terminating confirmed dialog\n");
        if (side == DLG_CALLER_LEG /* 0 */ || side == DLG_CALLEE_LEG /* 1 */) {
            if (dlg_bye(dlg, (extra_hdrs->len > 0) ? extra_hdrs : NULL, side) < 0)
                return -1;

        } else {
            if (dlg_bye_all(dlg, (extra_hdrs->len > 0) ? extra_hdrs : NULL) < 0)
                return -1;
        }
    }
    return 1;
}