Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

script_cb.c

Go to the documentation of this file.
00001 /*
00002  * $Id: script_cb.c,v 1.8 2006/06/16 11:48:39 tma0 Exp $
00003  *
00004  * Script callbacks -- they add the ability to register callback
00005  * functions which are always called when script for request
00006  * processing is entered or left
00007  *
00008  *
00009  * Copyright (C) 2001-2003 FhG Fokus
00010  *
00011  * This file is part of ser, a free SIP server.
00012  *
00013  * ser is free software; you can redistribute it and/or modify
00014  * it under the terms of the GNU General Public License as published by
00015  * the Free Software Foundation; either version 2 of the License, or
00016  * (at your option) any later version
00017  *
00018  * For a license to use the ser software under conditions
00019  * other than those described here, or to purchase support for this
00020  * software, please contact iptel.org by e-mail at the following addresses:
00021  *    info@iptel.org
00022  *
00023  * ser is distributed in the hope that it will be useful,
00024  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00025  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00026  * GNU General Public License for more details.
00027  *
00028  * You should have received a copy of the GNU General Public License 
00029  * along with this program; if not, write to the Free Software 
00030  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00031  *
00032  * History:
00033  * --------
00034  *  2003-03-29  cleaning pkg allocation introduced (jiri)
00035  *  2003-03-19  replaced all mallocs/frees w/ pkg_malloc/pkg_free (andrei)
00036  *  2005-02-13  script callbacks devided into request and reply types (bogdan)
00037  */
00038 
00039 
00040 #include <stdlib.h>
00041 #include "script_cb.h"
00042 #include "dprint.h"
00043 #include "error.h"
00044 #include "mem/mem.h"
00045 
00046 static struct script_cb *pre_req_cb=0;
00047 static struct script_cb *post_req_cb=0;
00048 
00049 static struct script_cb *pre_rpl_cb=0;
00050 static struct script_cb *post_rpl_cb=0;
00051 
00052 static unsigned int cb_id=0;
00053 
00054 
00055 static inline int add_callback( struct script_cb **list,
00056         cb_function f, void *param)
00057 {
00058         struct script_cb *new_cb;
00059 
00060         new_cb=pkg_malloc(sizeof(struct script_cb));
00061         if (new_cb==0) {
00062                 LOG(L_ERR, "ERROR:add_script_callback: out of memory\n");
00063                 return -1;
00064         }
00065         new_cb->cbf = f;
00066         new_cb->id = cb_id++;
00067         new_cb->param = param;
00068         /* link at the beginning of the list */
00069         new_cb->next = *list;
00070         *list = new_cb;
00071         return 0;
00072 }
00073 
00074 
00075 int register_script_cb( cb_function f, int type, void *param )
00076 {
00077         /* type checkings */
00078         if ( (type&(REQ_TYPE_CB|RPL_TYPE_CB))==0 ) {
00079                 LOG(L_CRIT,"BUG:register_script_cb: REQUEST or REPLY "
00080                         "type not specified\n");
00081                 goto error;
00082         }
00083         if ( (type&(PRE_SCRIPT_CB|POST_SCRIPT_CB))==0 ||
00084         (type&PRE_SCRIPT_CB && type&POST_SCRIPT_CB) ) {
00085                 LOG(L_CRIT,"BUG:register_script_cb: callback POST or PRE type must "
00086                         "be exactly one\n");
00087                 goto error;
00088         }
00089 
00090         if (type&REQ_TYPE_CB) {
00091                 /* callback for request script */
00092                 if (type&PRE_SCRIPT_CB) {
00093                         if (add_callback( &pre_req_cb, f, param)<0)
00094                                 goto add_error;
00095                 } else if (type&POST_SCRIPT_CB) {
00096                         if (add_callback( &post_req_cb, f, param)<0)
00097                                 goto add_error;
00098                 }
00099         }
00100         if (type&RPL_TYPE_CB) {
00101                 /* callback (also) for reply script */
00102                 if (type&PRE_SCRIPT_CB) {
00103                         if (add_callback( &pre_rpl_cb, f, param)<0)
00104                                 goto add_error;
00105                 } else if (type&POST_SCRIPT_CB) {
00106                         if (add_callback( &post_rpl_cb, f, param)<0)
00107                                 goto add_error;
00108                 }
00109         }
00110 
00111         return 0;
00112 add_error:
00113         LOG(L_ERR,"ERROR:register_script_cb: failed to add callback\n");
00114 error:
00115         return -1;
00116 }
00117 
00118 
00119 static inline void destroy_cb_list(struct script_cb **list)
00120 {
00121         struct script_cb *foo;
00122 
00123         while( *list ) {
00124                 foo = *list;
00125                 *list = (*list)->next;
00126                 pkg_free( foo );
00127         }
00128 }
00129 
00130 
00131 void destroy_script_cb()
00132 {
00133         destroy_cb_list( &pre_req_cb  );
00134         destroy_cb_list( &post_req_cb );
00135         destroy_cb_list( &pre_rpl_cb  );
00136         destroy_cb_list( &post_req_cb );
00137 }
00138 
00139 
00140 static inline int exec_pre_cb( struct sip_msg *msg, struct script_cb *cb)
00141 {
00142         for ( ; cb ; cb=cb->next ) {
00143                 /* stop on error */
00144                 if (cb->cbf(msg, cb->param)==0)
00145                         return 0;
00146         }
00147         return 1;
00148 }
00149 
00150 
00151 static inline int exec_post_cb( struct sip_msg *msg, struct script_cb *cb)
00152 {
00153         for ( ; cb ; cb=cb->next){
00154                 cb->cbf( msg, cb->param);
00155         }
00156         return 1;
00157 }
00158 
00159 
00160 int exec_pre_req_cb( struct sip_msg *msg)
00161 {
00162         return exec_pre_cb( msg, pre_req_cb);
00163 }
00164 
00165 int exec_pre_rpl_cb( struct sip_msg *msg)
00166 {
00167         return exec_pre_cb( msg, pre_rpl_cb);
00168 }
00169 
00170 int exec_post_req_cb( struct sip_msg *msg)
00171 {
00172         return exec_post_cb( msg, post_req_cb);
00173 }
00174 
00175 int exec_post_rpl_cb( struct sip_msg *msg)
00176 {
00177         return exec_post_cb( msg, post_rpl_cb);
00178 }
00179 

Generated on Thu Sep 9 04:16:04 2010 for SIPExpressRouter by  doxygen 1.3.9.1