Example #1
0
 /*
  * 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)); 
}
Example #2
0
/**
 * 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;
    }

}