/* Wrapper for terminating dialog from API - from other modules */ static void rpc_end_dlg_entry_id(rpc_t *rpc, void *c) { unsigned int h_entry, h_id; struct dlg_cell * dlg = NULL; str rpc_extra_hdrs = {NULL,0}; int n; n = rpc->scan(c, "dd", &h_entry, &h_id); if (n < 2) { LM_ERR("unable to read the parameters (%d)\n", n); rpc->fault(c, 500, "Invalid parameters"); return; } if(rpc->scan(c, "*S", &rpc_extra_hdrs)<1) { rpc_extra_hdrs.s = NULL; rpc_extra_hdrs.len = 0; } dlg = lookup_dlg(h_entry, h_id);//increments ref count! if(dlg==NULL) { rpc->fault(c, 404, "Dialog not found"); return; } unref_dlg(dlg, 1); dlg_terminate(dlg, NULL, NULL/*reason*/, 2, NULL); }
static int w_dlg_terminate(struct sip_msg *msg, char *side, char *r) { struct dlg_cell *dlg; str reason = {0, 0}; int n = (int) (long) side; //check if a reason was given if (r) { if (get_str_fparam(&reason, msg, (fparam_t *) r) < 0) { LM_ERR("failed to recover reason parameter\n"); return -1; } } dlg = dlg_get_msg_dialog(msg); //dlg_get_ctx_dialog(); if (!dlg) { LM_DBG("Unable to find dialog for terminate\n"); return -1; } if (!dlg_terminate(dlg, msg, &reason, n, NULL)) { LM_DBG("Failed to terminate dialog\n"); return -1; } return 1; }
/* Wrapper for terminating dialog from API - from other modules */ int w_api_lookup_terminate_dlg(unsigned int h_entry, unsigned int h_id, str *hdrs) { struct dlg_cell *dlg; dlg = lookup_dlg(h_entry, h_id); //increments ref count! if (!dlg) { LM_ERR("Asked to tear down non existent dialog\n"); return -1; } unref_dlg(dlg, 1); return dlg_terminate(dlg, NULL, NULL/*reason*/, 2, hdrs); }
/* Wrapper for terminating dialog from API - from other modules */ int w_api_terminate_dlg(str *callid, str *ftag, str *ttag, str *hdrs, str* reason) { struct dlg_cell *dlg; unsigned int dir = DLG_DIR_NONE; dlg = get_dlg(callid, ftag, ttag, &dir); //increments ref count! if (!dlg) { LM_ERR("Asked to tear down non existent dialog\n"); return -1; } unref_dlg(dlg, 1); return dlg_terminate(dlg, NULL, NULL/*reason*/, 2, hdrs); }
/* TODO: add reason parameter to mi interface */ struct mi_root * mi_terminate_dlg(struct mi_root *cmd_tree, void *param) { struct mi_node* node; struct dlg_cell * dlg = NULL; str mi_extra_hdrs = {NULL, 0}; int status, msg_len; char *msg; str callid = {NULL, 0}; str ftag = {NULL, 0}; str ttag = {NULL, 0}; if (d_table == NULL) goto end; node = cmd_tree->node.kids; if (node == NULL || node->next == NULL || node->next->next == NULL) return init_mi_tree(400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); if (!node->value.s || !node->value.len) { goto error; } else { callid = node->value; } node = node->next; if (!node->value.s || !node->value.len) { goto error; } else { ftag = node->value; } node = node->next; if (!node->value.s || !node->value.len) { goto error; } else { ttag = node->value; } if (node->next) { node = node->next; if (node->value.len && node->value.s) mi_extra_hdrs = node->value; } unsigned int dir = DLG_DIR_NONE; LM_DBG("Looking for callid [%.*s]\n", callid.len, callid.s); dlg = get_dlg(&callid, &ftag, &ttag, &dir); //increments ref count! if (dlg) { LM_DBG("Found dialog to terminate and it is in state [%i]\n", dlg->state); if (dlg_terminate(dlg, 0, NULL/*reson*/, /* all sides of a dialog*/ 2, &mi_extra_hdrs) < 0) { 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); }