/* * Any dialogs in state over CONFIRMED are going to be treated by * release_call_confirmed, its ok , but its a bit confusing because * some dialogs which were already treated by release_call_early may * end in release_call_confirmed if there is a second call to release_call_p * and they are already in state DLG_STATE_TERMINATED_ONE_SIDE.. it doesn't really * matter because both do the same at that point! */ int release_call_p(p_dialog *d,int reason_code,str reason_text) { if (d->state>=DLG_STATE_CONFIRMED) return(release_call_confirmed(d,reason_code,reason_text)); else return(release_call_early(d,reason_code,reason_text)); }
/** * Releases a call from the on reply route block * called with any reply to an INVITE * useful in cases of rejecting a call when you are processing the SDP * or handling QoS things * @msg - the sip message being processed * @str1 - the first parameter "orig" or "term" * @str2 - [optional] the Reason header that you want to go to the messages * @returns - BREAK ... whatever happens this message is not relayed */ int P_release_call_onreply(struct sip_msg *msg,char *str1,char *str2) { enum p_dialog_direction dir; p_dialog *d=NULL; str callid; struct hdr_field *h1; str reason= {NULL,0}; unsigned int hash; struct cell* t; /*needed to distinguish between UPDATE and INVITE*/ LOG(L_INFO,ANSI_WHITE"P_release_call_on_reply\n"); if (str2) { reason.s=str2; reason.len=strlen(str2); } else reason = _488_text_s; dir= (str1[0]=='o' || str1[0]=='O' || str1[0]=='0')? DLG_MOBILE_ORIGINATING : DLG_MOBILE_TERMINATING; if (msg->first_line.type== SIP_REQUEST) { LOG(L_ERR,"ERR: P_release_call_on_reply called with a request\n"); return CSCF_RETURN_FALSE; } callid=cscf_get_call_id(msg,&h1); if (is_p_dialog_dir(callid,dir)) { d=get_p_dialog_dir(callid,dir); hash=d->hash; t=tmb.t_gett(); if (!t) { LOG(L_ERR,"P_release_call_onreply(): unable to get transaction\n"); return CSCF_RETURN_BREAK; } if (t->method.len==6 && memcmp(t->method.s,"INVITE",6)==0) { // If its an INVTE, the state depends on which reply we are processing if (msg->first_line.u.reply.statuscode > 199) { release_call_previous(d,RELEASE_CALL_WEIRD,488,reason); } else { release_call_previous(d,RELEASE_CALL_EARLY,488,reason); } // This means we already finished with the dialog if (d->pcc_session_id.s) shm_free(d->pcc_session_id.s); d->pcc_session_id.s=0; d->pcc_session_id.len=0; d_unlock(hash); return CSCF_RETURN_BREAK; } else { //UPDATE so early release_call_early(d,488,reason); d_unlock(hash); return CSCF_RETURN_BREAK; } } else { LOG(L_ERR,"ERR:"M_NAME "P_release_call_onreply : unable to find dialog\n"); return CSCF_RETURN_ERROR; } }