Example #1
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 - TRUE on success or FALSE on misscall and BREAK on error
 */
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};
	
	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);
		if (msg->first_line.u.reply.statuscode > 199)
		{
			release_call_previous(d,RELEASE_CALL_WEIRD,488,reason);
			d_unlock(d->hash);
			return CSCF_RETURN_TRUE;
		} else {
			release_call_previous(d,RELEASE_CALL_EARLY,488,reason);
			d_unlock(d->hash);
			return CSCF_RETURN_TRUE;
		}
	} else {
		LOG(L_ERR,"ERR:"M_NAME "P_release_call_onreply :  unable to find dialog\n");
		return CSCF_RETURN_BREAK;
	}
	
}
Example #2
0
/*Send cancel and 503 or 488 */
int release_call_early(p_dialog *d,int reason_code,str reason_text)
{
	/*CANCEL will be badly routed because the response hasn't being processed
	 * it will be sent to I-CSCF who will relay to S-CSCF and from there to term@P-CSCF*/
	return release_call_previous(d,RELEASE_CALL_EARLY,reason_code,reason_text);
}
Example #3
0
/*send ACK,BYE and 503 or 488*/
int release_call_early200(p_dialog *d,int reason_code,str reason_text)
{
	return release_call_previous(d,RELEASE_CALL_WEIRD,reason_code,reason_text);
}
Example #4
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;
    }

}