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