t_reply.h

00001 /*
00002  * $Id$
00003  *
00004  * Copyright (C) 2001-2003 FhG Fokus
00005  *
00006  * This file is part of ser, a free SIP server.
00007  *
00008  * ser is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version
00012  *
00013  * For a license to use the ser software under conditions
00014  * other than those described here, or to purchase support for this
00015  * software, please contact iptel.org by e-mail at the following addresses:
00016  *    info@iptel.org
00017  *
00018  * ser is distributed in the hope that it will be useful,
00019  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021  * GNU General Public License for more details.
00022  *
00023  * You should have received a copy of the GNU General Public License 
00024  * along with this program; if not, write to the Free Software 
00025  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00026  */
00027 
00028 
00029 
00030 #ifndef _T_REPLY_H
00031 #define _T_REPLY_H
00032 
00033 /* CANCEL_REASON_SUPPORT on by default */
00034 #ifndef NO_CANCEL_REASON_SUPPORT
00035 #define CANCEL_REASON_SUPPORT
00036 #endif /* NO_CANCEL_REASON_SUPPORT */
00037 
00038 #include "defs.h"
00039 #include "../../rpc.h"
00040 #include "../../tags.h"
00041 
00042 #include "h_table.h"
00043 
00044 
00045 /* reply processing status */
00046 enum rps {
00047         /* something bad happened */
00048         RPS_ERROR=0,    
00049         /* transaction completed but we still accept the reply */
00050         RPS_PUSHED_AFTER_COMPLETION,
00051         /* reply discarded */
00052         RPS_DISCARDED,
00053         /* reply stored for later processing */
00054         RPS_STORE,
00055         /* transaction completed */
00056         RPS_COMPLETED,
00057         /* provisional reply not affecting transaction state */
00058         RPS_PROVISIONAL
00059 };
00060 
00061 extern char tm_tags[TOTAG_VALUE_LEN];
00062 extern char *tm_tag_suffix;
00063 
00064 extern int goto_on_sl_reply;
00065 
00066 extern int failure_reply_mode;
00067 
00068 extern int faked_reply_prio;
00069 
00070 extern int tm_rich_redirect;
00071  
00072 /* has this to-tag been never seen in previous 200/INVs? */
00073 int unmatched_totag(struct cell *t, struct sip_msg *ack);
00074 
00075 /* branch bitmap type */
00076 typedef unsigned int branch_bm_t;
00077 
00078 #ifdef CANCEL_REASON_SUPPORT
00079 
00080 /* reason building blocks (see rfc3326) */
00081 #define REASON_PREFIX "Reason: SIP;cause="
00082 #define REASON_PREFIX_LEN (sizeof(REASON_PREFIX)-1)
00083 #define REASON_TEXT ";text="
00084 #define REASON_TEXT_LEN (sizeof(REASON_TEXT)-1)
00085 
00086 #define CANCEL_REAS_UNKNOWN 0
00087 #define CANCEL_REAS_PACKED_HDRS -1
00088 #define CANCEL_REAS_RCVD_CANCEL -2
00089 #define CANCEL_REAS_FINAL_REPLY(x) (x)
00090 #define CANCEL_REAS_MIN CANCEL_REAS_RCVD_CANCEL
00091 
00092 
00094 struct cancel_reason {
00095         short cause; 
00096         union{
00097                 str text; 
00098                 struct sip_msg* e2e_cancel; 
00099                 str packed_hdrs; 
00100         }u;
00101 };
00102 
00103 struct cancel_info {
00104         branch_bm_t cancel_bitmap; 
00105         struct cancel_reason reason;
00106 };
00107 
00108 
00109 #define init_cancel_reason(cr) \
00110         do {\
00111                 (cr)->cause=0; \
00112                 (cr)->u.e2e_cancel=0; \
00113         } while(0)
00114 
00115 #define init_cancel_info(ci) \
00116         do {\
00117                 (ci)->cancel_bitmap=0; \
00118                 init_cancel_reason(&(ci)->reason); \
00119         }while (0);
00120 
00121 #else /* ! CANCEL_REASON_SUPPORT */
00122 
00123 struct cancel_info {
00124         branch_bm_t cancel_bitmap; 
00125 };
00126 
00127 #define init_cancel_info(ci) \
00128         do {\
00129                 (ci)->cancel_bitmap=0; \
00130         }while (0);
00131 
00132 #endif /* CANCEL_REASON_SUPPORT */
00133 
00134 
00135 /* reply export types */
00136 typedef int (*treply_f)(struct sip_msg * , unsigned int , char * );
00137 typedef int (*treply_wb_f)( struct cell* trans,
00138         unsigned int code, str *text, str *body,
00139         str *new_header, str *to_tag);
00140 typedef int (*treply_trans_f)(struct cell *t, struct sip_msg* p_msg, unsigned int code,
00141         char * text);
00142 
00143 /* wrapper function needed after changes in w_t_reply */
00144 int w_t_reply_wrp(struct sip_msg *m, unsigned int code, char *txt);
00145 
00146 typedef int (*tget_reply_totag_f)(struct sip_msg *, str *);
00147 int t_get_reply_totag(struct sip_msg *msg, str *totag);
00148 
00149 #define LOCK_REPLIES(_t) lock(&(_t)->reply_mutex )
00150 #define UNLOCK_REPLIES(_t) unlock(&(_t)->reply_mutex )
00151 
00152 /* This function is called whenever a reply for our module is received;
00153  * we need to register this function on module initialization;
00154  * Returns :   0 - core router stops
00155  *             1 - core router relay statelessly
00156  */
00157 int reply_received( struct sip_msg  *p_msg ) ;
00158 
00159 /* return 1 if a failure_route processes */
00160 int run_failure_handlers(struct cell *t, struct sip_msg *rpl,
00161                                         int code, int extra_flags);
00162 typedef int (*run_failure_handlers_f)(struct cell*, struct sip_msg*, int, int);
00163 
00164 
00165 /* Retransmits the last sent inbound reply.
00166  * Returns  -1 - error
00167  *           1 - OK
00168  
00169  *int t_retransmit_reply(struct sip_msg *);
00170 */
00171 
00172 /* send a UAS reply
00173  * Warning: 'buf' and 'len' should already have been build.
00174  * returns 1 if everything was OK or -1 for error
00175  */
00176 
00177 
00178 int t_reply_with_body(struct cell *trans, unsigned int code,
00179                 str *text, str *body, str *new_header, str *to_tag);
00180 
00181 
00182 /* send a UAS reply
00183  * returns 1 if everything was OK or -1 for error
00184  */
00185 int t_reply( struct cell *t, struct sip_msg * , unsigned int , char * );
00186 /* the same as t_reply, except it does not claim
00187    REPLY_LOCK -- useful to be called within reply
00188    processing
00189 */
00190 int t_reply_unsafe( struct cell *t, struct sip_msg * , unsigned int , char * );
00191 
00192 
00193 enum rps relay_reply( struct cell *t, struct sip_msg *p_msg, int branch,
00194         unsigned int msg_status, struct cancel_info *cancel_data,
00195         int do_put_on_wait );
00196 
00197 enum rps local_reply( struct cell *t, struct sip_msg *p_msg, int branch,
00198         unsigned int msg_status, struct cancel_info *cancel_data );
00199 
00200 void set_final_timer( /* struct s_table *h_table,*/ struct cell *t );
00201 
00202 void cleanup_uac_timers( struct cell *t );
00203 
00204 void on_negative_reply( struct cell* t, struct sip_msg* msg,
00205         int code, void *param  );
00206 
00207 /* set which 'reply' structure to take if only negative
00208    replies arrive 
00209 */
00210 void t_on_negative( unsigned int go_to );
00211 unsigned int get_on_negative(void);
00212 void t_on_reply( unsigned int go_to );
00213 unsigned int get_on_reply(void);
00214 
00215 int t_retransmit_reply( struct cell *t );
00216 
00217 void tm_init_tags(void);
00218 
00219 /* selects the branch for fwd-ing the reply */
00220 int t_pick_branch(int inc_branch, int inc_code, struct cell *t, int *res_code);
00221 /* checks the selected branch from failure_route */
00222 int t_pick_branch_blind(struct cell *t, int *res_code);
00223 
00224 /* drops all the replies to make sure
00225  * that none of them is picked up again
00226  */
00227 void t_drop_replies(int v);
00228 
00229 void rpc_reply(rpc_t* rpc, void* c);
00230 
00231 void faked_env( struct cell *t,struct sip_msg *msg);
00232 int fake_req(struct sip_msg *faked_req,
00233                 struct sip_msg *shmem_msg, int extra_flags, struct ua_client *uac);
00234 
00235 void free_faked_req(struct sip_msg *faked_req, struct cell *t);
00236 
00237 typedef int (*tget_picked_f)(void);
00238 int t_get_picked_branch(void);
00239 
00240 #endif