/* sends BYE in both directions * returns 0 if both BYEs were successful */ int dlg_end_dlg(struct dlg_cell *dlg, str *extra_hdrs, int send_byes) { str str_hdr = {NULL,0}; struct cell* t; int i,res = 0; int callee; /* lookup_dlg has incremented the reference count !! */ if (send_byes && (dlg->state == DLG_STATE_UNCONFIRMED || dlg->state == DLG_STATE_EARLY)) { /* locate initial transaction */ LM_DBG("trying to find transaction with hash_index = %u and label = %u\n", dlg->initial_t_hash_index,dlg->initial_t_label); if (d_tmb.t_lookup_ident(&t,dlg->initial_t_hash_index,dlg->initial_t_label) < 0) { LM_ERR("Initial transaction does not exist any more\n"); return -1; } if (d_tmb.t_cancel_trans(t,NULL) < 0) { LM_ERR("Failed to send cancels\n"); d_tmb.unref_cell(t); return -1; } /* lookup_ident refs the transaction */ d_tmb.unref_cell(t); return 0; } if (send_byes && (build_extra_hdr(dlg, extra_hdrs, &str_hdr)) != 0){ LM_ERR("failed to create extra headers\n"); return -1; } callee = callee_idx(dlg); if (send_byes && send_leg_bye(dlg, DLG_CALLER_LEG, callee, &str_hdr)!=0) { res--; } if (send_byes && send_leg_bye(dlg, callee, DLG_CALLER_LEG, &str_hdr)!=0 ) { res--; } if (!send_byes) { dual_bye_event(dlg, NULL, 0); dual_bye_event(dlg, NULL, 0); } else for(i=res ; i<0 ; i++) dual_bye_event(dlg, NULL, 1); if (str_hdr.s) pkg_free(str_hdr.s); return res; }
/*callback function to handle responses to the BYE request */ void bye_reply_cb(struct cell* t, int type, struct tmcb_params* ps) { if(ps->param == NULL || *ps->param == NULL){ LM_ERR("invalid parameter\n"); return; } if(ps->code < 200){ LM_DBG("receiving a provisional reply\n"); return; } LM_DBG("receiving a final reply %d\n",ps->code); /* mark the transaction as belonging to this dialog */ t->dialog_ctx = *(ps->param); dual_bye_event( (struct dlg_cell *)(*(ps->param)), ps->req, 1); }