/** * Given an s_dialog, releases the call. * This function is already called with a lock in d * after returning d should be unlocked. * @param d - pointer to the s_dialog structure * @param reason - Reason header to include * @returns -1 if dialog the dialog is not confirmed, 0 on error or 1 on success */ int release_call_s(s_dialog *d,str reason) { enum s_dialog_direction odir; s_dialog *o; LOG(L_INFO,"DBG:"M_NAME":release_call_s(): Releasing call <%.*s> DIR[%d].\n", d->call_id.len,d->call_id.s,d->direction); /* As for now, i'm only releasing confirmed dialogs */ if (d->state < DLG_STATE_CONFIRMED){ LOG(L_INFO,"ERR:"M_NAME":release_call_s(): Unable to release a non-confirmed dialog\n"); return -1; } /* get the dialog in the other direction to see if something going on there and mark as in releasing */ switch (d->direction){ case DLG_MOBILE_ORIGINATING: odir = DLG_MOBILE_TERMINATING; break; case DLG_MOBILE_TERMINATING: odir = DLG_MOBILE_ORIGINATING; break; default: odir = d->direction; } o = get_s_dialog_dir_nolock(d->call_id,odir); if (o && !o->is_releasing) o->is_releasing = 1; d->is_releasing++; if (d->is_releasing>MAX_TIMES_TO_TRY_TO_RELEASE){ LOG(L_ERR,"ERR:"M_NAME":release_call_s(): had to delete silently dialog %.*s in direction %i\n",d->call_id.len,d->call_id.s,d->direction); del_s_dialog(d); return 0; } if (d->is_releasing==1) { /*Before generating a request, we have to generate * the route_set in the dlg , because the route set * in the dialog is for the UAC everything which was in the * Record-Routes (including local address)*/ alter_dialog_route_set(d->dialog_c,d->direction); /*first generate the bye for called user*/ /*then generate the bye for the calling user*/ send_bye(d->dialog_c,bye_response,d->direction,reason); send_bye(d->dialog_s,bye_response,d->direction,reason); /*the dialog is droped by the callback-function when recieves the two replies */ } return 1; }
int dlg_bye_all(struct dlg_cell *dlg, str *hdrs) { str all_hdrs = {0, 0}; int ret; if ((build_extra_hdr(dlg, hdrs, &all_hdrs)) != 0) { LM_ERR("failed to build dlg headers\n"); return -1; } ret = send_bye(dlg, DLG_CALLER_LEG, &all_hdrs); ret |= send_bye(dlg, DLG_CALLEE_LEG, &all_hdrs); pkg_free(all_hdrs.s); return ret; }
void msn_slp_call_close(MsnSlpCall *slpcall) { g_return_if_fail(slpcall != NULL); g_return_if_fail(slpcall->slplink != NULL); send_bye(slpcall, "application/x-msnmsgr-sessionclosebody"); msn_slplink_unleash(slpcall->slplink); msn_slp_call_destroy(slpcall); }
int dlg_bye(struct dlg_cell *dlg, str *hdrs, int side) { str all_hdrs = {0, 0}; int ret; if (side == DLG_CALLER_LEG) { if (dlg->dflags & DLG_FLAG_CALLERBYE) return -1; dlg->dflags |= DLG_FLAG_CALLERBYE; } else { if (dlg->dflags & DLG_FLAG_CALLEEBYE) return -1; dlg->dflags |= DLG_FLAG_CALLEEBYE; } if ((build_extra_hdr(dlg, hdrs, &all_hdrs)) != 0) { LM_ERR("failed to build dlg headers\n"); return -1; } ret = send_bye(dlg, side, &all_hdrs); pkg_free(all_hdrs.s); return ret; }
int do_extract() { guint i; ProtoBye pb; if(int_option(kOption_verbose) & VERBOSE_FLOW) g_message("begin do_extract"); if(g_args->len == 0) { extract_it(NULL); } else { for(i = 0; i < g_args->len; i++) extract_it((const char *)g_ptr_array_index(g_args, i)); } if(int_option(kOption_verbose) & VERBOSE_FLOW) g_message("end do_extract"); if(!wt_more()) { memset(&pb, 0, sizeof(pb)); pb.error = pbe_OK; send_bye(&pb); } return 0; }