- avp core replaced with .14 version
authorBogdan-Andrei Iancu <bogdan@voice-system.ro>
Mon, 23 Aug 2004 20:47:51 +0000 (20:47 +0000)
committerBogdan-Andrei Iancu <bogdan@voice-system.ro>
Mon, 23 Aug 2004 20:47:51 +0000 (20:47 +0000)
- avp DB support removed from core (later to be added as separate module)
- tm support for avps (avp list saved into transactions and made available into
  tm callbacks, in failure and reply routes).

13 files changed:
action.c
cfg.lex
cfg.y
main.c
modules/tm/h_table.c
modules/tm/h_table.h
modules/tm/t_fifo.c
modules/tm/t_hooks.c
modules/tm/t_reply.c
modules/tm/uac.c
receive.c
usr_avp.c
usr_avp.h

index 23d04b1..882a592 100644 (file)
--- a/action.c
+++ b/action.c
@@ -36,7 +36,6 @@
  *  2003-04-22  strip_tail added (jiri)
  *  2003-10-02  added SET_ADV_ADDR_T & SET_ADV_PORT_T (andrei)
  *  2003-10-29  added FORCE_TCP_ALIAS_T (andrei)
- *  2004-02-24  added LOAD_AVP_T and AVP_TO_URI_T (bogdan)
  */
 
 
@@ -57,7 +56,6 @@
 #include "mem/mem.h"
 #include "globals.h"
 #include "dset.h"
-#include "usr_avp.h"
 #ifdef USE_TCP
 #include "tcp_server.h"
 #endif
@@ -90,7 +88,6 @@ int do_action(struct action* a, struct sip_msg* msg)
        int len;
        int user;
        struct sip_uri uri, next_hop;
-       struct usr_avp *avp;
        struct sip_uri *u;
        unsigned short port;
        int proto;
@@ -661,58 +658,6 @@ int do_action(struct action* a, struct sip_msg* msg)
 #endif
                        ret=1; /* continue processing */
                        break;
-               case LOAD_AVP_T:
-                       if (a->p1_type!=NUMBER_ST || a->p2_type!=STRING_ST ||
-                       a->p3_type!=NUMBER_ST) {
-                               LOG(L_CRIT,"BUG: do_action: bad load_avp(%d,%d,%d) params "
-                                               "types\n",a->p1_type,a->p2_type,a->p3_type);
-                               ret=E_BUG;
-                               break;
-                       }
-                       /* load the attribute(s)*/
-                       if ( (ret=load_avp( msg, (int)a->p1.number, a->p2.string,
-                       (int)a->p3.number))==-1 ) {
-                               LOG(L_ERR,"ERROR:do_action: load avp failed\n");
-                               ret=E_UNSPEC;
-                               break;
-                       }
-                       ret = (ret==0)?1/*success*/:E_UNSPEC/*notfound*/;
-                       break;
-               case AVP_TO_URI_T:
-                       if (a->p1_type!=STR_ST ) {
-                               LOG(L_CRIT,"BUG: do_action: bad avp_to_uri(%d) params "
-                                               "types\n",a->p1_type);
-                               ret=E_BUG;
-                               break;
-                       }
-                       /* look for the attribute */
-                       if ( (avp=search_avp( (str*)a->p1.string ))==0) {
-                               ret=E_UNSPEC;
-                               break;
-                       }
-                       if (avp->val_type!=AVP_TYPE_STR) {
-                               LOG(L_ERR,"ERROR:do_action: in avp_to_uri attribute <%s> "
-                                       "doesn't has a STR value\n",((str*)a->p1.string)->s);
-                               ret=E_UNSPEC;
-                               break;
-                       }
-                       /* replace the ruri */
-                       new_uri = (char*)pkg_malloc( avp->val.str_val.len+1 );
-                       if (new_uri==0) {
-                               LOG(L_ERR,"ERROR:tm:t_attr_to_uri: no more pkg memory\n");
-                               ret = E_OUT_OF_MEM;
-                               break;
-                       }
-                       memcpy( new_uri, avp->val.str_val.s, avp->val.str_val.len);
-                       new_uri[avp->val.str_val.len] = 0;
-                       if (msg->new_uri.s)
-                               pkg_free( msg->new_uri.s );
-                       msg->new_uri.s = new_uri;
-                       msg->new_uri.len = avp->val.str_val.len;
-                       msg->parsed_uri_ok=0;
-
-                       ret = 1;
-                       break;
                default:
                        LOG(L_CRIT, "BUG: do_action: unknown type %d\n", a->type);
        }
diff --git a/cfg.lex b/cfg.lex
index cbf4b5b..1e28409 100644 (file)
--- a/cfg.lex
+++ b/cfg.lex
@@ -44,7 +44,6 @@
  *  2003-10-13  added fifo_dir (andrei)
  *  2003-10-28  added tcp_accept_aliases (andrei)
  *  2003-11-29  added {tcp_send, tcp_connect, tls_*}_timeout (andrei)
- *  2004-02-24  added LOAD_AVP_T and AVP_TO_URI_T (bogdan)
  *  2004-03-30  added DISABLE_CORE and OPEN_FD_LIMIT (andrei)
  *  2004-04-28  added sock_mode (replaces fifo_mode), sock_user &
  *               sock_group  (andrei)
@@ -120,8 +119,6 @@ IF                          "if"
 ELSE                   "else"
 SET_ADV_ADDRESS        "set_advertised_address"
 SET_ADV_PORT   "set_advertised_port"
-LOAD_AVP               "load_avp"
-AVP_TO_URI             "avp_to_uri"
 
 /*ACTION LVALUES*/
 URIHOST                        "uri:host"
@@ -184,7 +181,6 @@ FIFO_DB_URL fifo_db_url
 UNIX_SOCK unix_sock
 UNIX_SOCK_CHILDREN unix_sock_children
 UNIX_TX_TIMEOUT unix_tx_timeout
-AVP_DB_URL  avp_db_url
 SERVER_SIGNATURE server_signature
 REPLY_TO_VIA reply_to_via
 USER           "user"|"uid"
@@ -304,9 +300,6 @@ EAT_ABLE    [\ \t\b\r]
 <INITIAL>{FORCE_RPORT} { count(); yylval.strval=yytext; return FORCE_RPORT; }
 <INITIAL>{FORCE_TCP_ALIAS}     { count(); yylval.strval=yytext;
                                                                return FORCE_TCP_ALIAS; }
-<INITIAL>{LOAD_AVP}    { count(); yylval.strval=yytext; return LOAD_AVP; }
-<INITIAL>{AVP_TO_URI}  { count(); yylval.strval=yytext; return AVP_TO_URI; }
-       
 <INITIAL>{IF}  { count(); yylval.strval=yytext; return IF; }
 <INITIAL>{ELSE}        { count(); yylval.strval=yytext; return ELSE; }
 
@@ -385,7 +378,6 @@ EAT_ABLE    [\ \t\b\r]
 <INITIAL>{UNIX_SOCK} { count(); yylval.strval=yytext; return UNIX_SOCK; }
 <INITIAL>{UNIX_SOCK_CHILDREN} { count(); yylval.strval=yytext; return UNIX_SOCK_CHILDREN; }
 <INITIAL>{UNIX_TX_TIMEOUT} { count(); yylval.strval=yytext; return UNIX_TX_TIMEOUT; }
-<INITIAL>{AVP_DB_URL}  { count(); yylval.strval=yytext; return AVP_DB_URL; }
 <INITIAL>{SERVER_SIGNATURE}    { count(); yylval.strval=yytext; return SERVER_SIGNATURE; }
 <INITIAL>{REPLY_TO_VIA}        { count(); yylval.strval=yytext; return REPLY_TO_VIA; }
 <INITIAL>{ADVERTISED_ADDRESS}  {       count(); yylval.strval=yytext;
diff --git a/cfg.y b/cfg.y
index 271937f..8cdf829 100644 (file)
--- a/cfg.y
+++ b/cfg.y
@@ -50,7 +50,6 @@
  * 2003-10-24  converted to the new socket_info lists (andrei)
  * 2003-10-28  added tcp_accept_aliases (andrei)
  * 2003-11-20  added {tcp_connect, tcp_send, tls_*}_timeout (andrei)
- * 2004-02-24  added LOAD_AVP_T and AVP_TO_URI_T (bogdan)
  * 2004-03-30  added DISABLE_CORE and OPEN_FD_LIMIT (andrei)
  * 2004-04-29  added SOCK_MODE, SOCK_USER & SOCK_GROUP (andrei)
  * 2004-05-03  applied multicast support patch (MCAST_LOOPBACK) from janakj
@@ -80,7 +79,6 @@
 #include "resolve.h"
 #include "socket_info.h"
 #include "name_alias.h"
-#include "usr_avp.h"
 #include "ut.h"
 #include "dset.h"
 
@@ -186,8 +184,6 @@ static struct id_list* mk_listen_id(char*, int, int);
 %token UDP
 %token TCP
 %token TLS
-%token LOAD_AVP
-%token AVP_TO_URI
 
 /* config vars. */
 %token DEBUG
@@ -214,7 +210,6 @@ static struct id_list* mk_listen_id(char*, int, int);
 %token UNIX_SOCK
 %token UNIX_SOCK_CHILDREN
 %token UNIX_TX_TIMEOUT
-%token AVP_DB_URL
 %token SERVER_SIGNATURE
 %token REPLY_TO_VIA
 %token LOADMODULE
@@ -438,8 +433,6 @@ assign_stm: DEBUG EQUAL NUMBER { debug=$3; }
                | UNIX_SOCK_CHILDREN EQUAL error { yyerror("int value expected\n"); }
                | UNIX_TX_TIMEOUT EQUAL NUMBER { unixsock_tx_timeout=$3; }
                | UNIX_TX_TIMEOUT EQUAL error { yyerror("int value expected\n"); }
-               | AVP_DB_URL EQUAL STRING { avp_db_url=$3; }
-               | AVP_DB_URL EQUAL error  { yyerror("string value expected"); }
                | USER EQUAL STRING     { user=$3; }
                | USER EQUAL ID         { user=$3; }
                | USER EQUAL error      { yyerror("string value expected"); }
@@ -1561,40 +1554,6 @@ cmd:             FORWARD LPAREN host RPAREN      { $$=mk_action( FORWARD_T,
                | FORCE_TCP_ALIAS LPAREN error RPAREN   {$$=0; 
                                        yyerror("bad argument, number expected");
                                        }
-               | LOAD_AVP LPAREN STRING COMMA NUMBER RPAREN {
-                                       $$=(void*)get_user_type( $3 );
-                                       if ($$==(void*)-1) {
-                                               yyerror("unknown user type in arg 1 for "
-                                                       "load_avp(x,x)");
-                                       } else {
-                                               $$=mk_action3( LOAD_AVP_T, NUMBER_ST, STRING_ST,
-                                                       NUMBER_ST, $$, 0,(void*)$5);
-                                       }
-                                       }
-               | LOAD_AVP LPAREN STRING COMMA STRING COMMA NUMBER RPAREN {
-                                       $$=(void*)get_user_type( $3 );
-                                       if ($$==(void*)-1) {
-                                               yyerror("unknown user type in arg 1 for "
-                                                       "load_avp(x,x,x)");
-                                       } else {
-                                               $$=mk_action3( LOAD_AVP_T, NUMBER_ST, STRING_ST,
-                                                       NUMBER_ST, $$, $5, (void*)$7);
-                                       }
-                                       }
-               | LOAD_AVP error { $$=0; yyerror("missing '(' or ')' ?"); }
-               | AVP_TO_URI LPAREN STRING RPAREN {
-                                                               $$=0;
-                                                               if ((str_tmp=pkg_malloc(sizeof(str)))==0){
-                                                                               LOG(L_CRIT, "ERROR: cfg. parser:"
-                                                                                                       " out of memory.\n");
-                                                               }else{
-                                                                               str_tmp->s=$3;
-                                                                               str_tmp->len=strlen($3);
-                                                                               $$=mk_action(AVP_TO_URI_T, STR_ST,
-                                                                                       0, str_tmp, 0);
-                                                               }
-                                                                               }
-               | AVP_TO_URI error { $$=0; yyerror("missing '(' or ')' ?"); }
                | SET_ADV_ADDRESS LPAREN listen_id RPAREN {
                                                                $$=0;
                                                                if ((str_tmp=pkg_malloc(sizeof(str)))==0){
diff --git a/main.c b/main.c
index cc3ff16..9050c25 100644 (file)
--- a/main.c
+++ b/main.c
@@ -45,7 +45,6 @@
  *  2003-06-29  replaced port_no_str snprintf w/ int2str (andrei)
  *  2003-10-10  added switch for config check (-c) (andrei)
  *  2003-10-24  converted to the new socket_info lists (andrei)
- *  2004-02-06  added support for user pref. - init_avp_child() (bogdan)
  *  2004-03-30  core dump is enabled by default
  *              added support for increasing the open files limit    (andrei)
  *  2004-04-28  sock_{user,group,uid,gid,mode} added
 #include "parser/digest/digest_parser.h"
 #include "fifo_server.h"
 #include "unixsock_server.h"
-#include "usr_avp.h"
 #include "name_alias.h"
 #include "hash_func.h"
 #include "pt.h"
@@ -826,10 +824,6 @@ int main_loop()
                        LOG(L_ERR, "main_dontfork: init_child failed\n");
                        goto error;
                }
-               if (init_avp_child(1)<0) {
-                       LOG(L_ERR, "init_avp_child failed\n");
-                       goto error;
-               }
 
                is_main=1; /* hack 42: call init_child with is_main=0 in case
                                         some modules wants to fork a child */
@@ -944,10 +938,6 @@ int main_loop()
                                        }
 #endif
                                        bind_address=si; /* shortcut */
-                                       if (init_avp_child(i + 1)<0) {
-                                               LOG(L_ERR, "init_avp_child failed\n");
-                                               goto error;
-                                       }
                                        if (init_child(i + 1) < 0) {
                                                LOG(L_ERR, "init_child failed\n");
                                                goto error;
index 3301f54..5823541 100644 (file)
@@ -39,6 +39,8 @@
  * 2004-02-11  FIFO/CANCEL + alignments (hash=f(callid,cseq)) (uli+jiri)
  * 2004-02-13  t->is_invite and t->local replaced with flags;
  *             timer_link.payload removed (bogdan)
+ * 2004-08-23  avp support added - move and remove avp list to/from
+ *             transactions (bogdan)
  */
 
 #include <stdlib.h>
@@ -157,6 +159,10 @@ void free_cell( struct cell* dead_cell )
                tt=foo;
        }
 
+       /* free the avp list */
+       if (dead_cell->user_avps)
+               destroy_avp_list_unsafe( &dead_cell->user_avps );
+
        /* the cell's body */
        shm_free_unsafe( dead_cell );
 
@@ -219,6 +225,7 @@ struct cell*  build_cell( struct sip_msg* p_msg )
 {
        struct cell* new_cell;
        int          sip_msg_len;
+       struct usr_avp **old;
 
        /* allocs a new cell */
        new_cell = (struct cell*)shm_malloc( sizeof( struct cell ) );
@@ -237,6 +244,11 @@ struct cell*  build_cell( struct sip_msg* p_msg )
 #endif
        new_cell->uas.response.my_T=new_cell;
 
+       /* move the current avp list to transaction -bogdan */
+       old = set_avp_list( &new_cell->user_avps );
+       new_cell->user_avps = *old;
+       *old = 0;
+
        /* enter callback, which may potentially want to parse some stuff,
         * before the request is shmem-ized */
        if ( p_msg && has_reqin_tmcbs() )
@@ -265,6 +277,8 @@ struct cell*  build_cell( struct sip_msg* p_msg )
 
 error:
        shm_free(new_cell);
+       /* unlink transaction AVP list and link back the global AVP list (bogdan)*/
+       reset_avps();
        return NULL;
 }
 
index 37852aa..8da8c60 100644 (file)
@@ -32,8 +32,9 @@
  * 2003-12-04  callbacks per transaction added; completion callback
  *             merge into them as LOCAL_COMPETED (bogdan)
  * 2004-02-11  FIFO/CANCEL + alignments (hash=f(callid,cseq)) (uli+jiri)
- * 2004-02-13: t->is_invite, t->local, t->noisy_ctimer replaced
+ * 2004-02-13  t->is_invite, t->local, t->noisy_ctimer replaced
  *             with flags (bogdan)
+ * 2004-08-23  avp support added - avp list linked in transaction (bogdan)
  */
 
 #include "defs.h"
@@ -48,6 +49,7 @@
 #include "../../parser/msg_parser.h"
 #include "../../types.h"
 #include "../../md5utils.h"
+#include "../../usr_avp.h"
 #include "config.h"
 
 struct s_table;
@@ -249,6 +251,9 @@ typedef struct cell
         * forwarded or passed to UAC; note that there can be arbitrarily 
         * many due to downstream forking; */
        struct totag_elem *fwded_totags;
+
+       /* list with user avp */
+       struct usr_avp *user_avps;
 }cell_type;
 
 
index 50ade5a..736d671 100644 (file)
@@ -184,6 +184,7 @@ error:
 }
 
 
+#define EMAIL_AVP_ID  0xcaca
 static int assemble_msg(struct sip_msg* msg, char* action)
 {
        static char     id_buf[IDBUF_LEN];
@@ -191,7 +192,7 @@ static int assemble_msg(struct sip_msg* msg, char* action)
        static char     hdrs_buf[HDRS_BUFFER_MAX];
        static char     cmd_buf[CMD_BUFFER_MAX];
        static str      empty_param = {".",1};
-       static str      email_attr = {"email",5};
+       int_str           email_val;
        unsigned int      hash_index, label;
        contact_body_t*   cb=0;
        contact_t*        c=0;
@@ -199,7 +200,6 @@ static int assemble_msg(struct sip_msg* msg, char* action)
        rr_t*             record_route;
        struct hdr_field* p_hdr;
        param_hooks_t     hooks;
-       struct usr_avp    *email_avp;
        int               l;
        char*             s, fproxy_lr;
        str               route, next_hop, hdrs, tmp_s, body, str_uri;
@@ -210,7 +210,7 @@ static int assemble_msg(struct sip_msg* msg, char* action)
                goto error;
        }
 
-       email_avp = 0;
+       email_val.s = 0;
        body = empty_param;
 
        /* parse all -- we will need every header field for a UAS */
@@ -344,12 +344,7 @@ static int assemble_msg(struct sip_msg* msg, char* action)
                body.len = msg->len - (body.s - msg->buf);
 
                /* get email (if any) */
-               if ( (email_avp=search_avp( &email_attr ))!=0 &&
-               email_avp->val_type!=AVP_TYPE_STR ) {
-                       LOG(L_WARN, "assemble_msg: 'email' avp found but "
-                           "not string -> ignoring it\n");
-                       email_avp = 0;
-               }
+               search_first_avp( 0, (int_str)EMAIL_AVP_ID, &email_val);
        }
 
        /* additional headers */
@@ -400,7 +395,7 @@ static int assemble_msg(struct sip_msg* msg, char* action)
 
        eol_line(2)=REQ_LINE(msg).method;     /* method type */
        eol_line(3)=msg->parsed_uri.user;     /* user from r-uri */
-       eol_line(4)=email_avp?(email_avp->val.str_val):empty_param;  /* email */
+       eol_line(4)=(email_val.s)?(*email_val.s):(empty_param);  /* email */
        eol_line(5)=msg->parsed_uri.host;     /* domain */
 
        eol_line(6)=msg->rcv.bind_address->address_str; /* dst ip */
index 868bca2..6825493 100644 (file)
@@ -31,6 +31,8 @@
  *  2003-12-04  global callbacks moved into transaction callbacks;
  *              multiple events per callback added; single list per
  *              transaction for all its callbacks (bogdan)
+ *  2004-08-23  user avp(attribute value pair) added -> making avp list
+ *              available in callbacks (bogdan)
  */
 
 #include "defs.h"
@@ -40,6 +42,7 @@
 #include "../../dprint.h"
 #include "../../error.h"
 #include "../../mem/mem.h"
+#include "../../usr_avp.h"
 #include "t_hooks.h"
 #include "t_lookup.h"
 #include "t_funcs.h"
@@ -169,11 +172,16 @@ void run_trans_callbacks( int type , struct cell *trans,
 {
        static struct tmcb_params params = {0,0,0,0};
        struct tm_callback    *cbp;
+       struct usr_avp **backup;
 
        params.req = req;
        params.rpl = rpl;
        params.code = code;
 
+       if (trans->tmcb_hl.first==0 || ((trans->tmcb_hl.reg_types)&type)==0 )
+               return;
+
+       backup = set_avp_list( &trans->user_avps );
        for (cbp=trans->tmcb_hl.first; cbp; cbp=cbp->next)  {
                if ( (cbp->types)&type ) {
                        DBG("DBG: trans=%p, callback type %d, id %d entered\n",
@@ -181,6 +189,7 @@ void run_trans_callbacks( int type , struct cell *trans,
                        params.param = &(cbp->param);
                        cbp->callback( trans, type, &params );
                }
+       set_avp_list( backup );
        }
 }
 
@@ -190,15 +199,21 @@ void run_reqin_callbacks( struct cell *trans, struct sip_msg *req, int code )
 {
        static struct tmcb_params params = {0,0,0,0};
        struct tm_callback    *cbp;
+       struct usr_avp **backup;
 
        params.req = req;
        params.code = code;
 
+       if (req_in_tmcb_hl->first==0)
+               return;
+
+       backup = set_avp_list( &trans->user_avps );
        for (cbp=req_in_tmcb_hl->first; cbp; cbp=cbp->next)  {
                DBG("DBG: trans=%p, callback type %d, id %d entered\n",
                        trans, cbp->types, cbp->id );
                params.param = &(cbp->param);
                cbp->callback( trans, cbp->types, &params );
        }
+       set_avp_list( backup );
 }
 
index fb59b9a..11243f2 100644 (file)
@@ -60,6 +60,7 @@
  *  2003-11-11: build_lump_rpl() removed, add_lump_rpl() has flags (bogdan)
  *  2004-02-13: t->is_invite and t->local replaced with flags (bogdan)
  *  2004-02-18  fifo_t_reply imported from vm module (bogdan)
+ *  2004-08-23  avp list is available from failure/on_reply routes (bogdan)
  */
 
 
@@ -473,31 +474,36 @@ static inline void faked_env( struct cell *t,struct sip_msg *msg)
        static enum route_mode backup_mode;
        static struct cell *backup_t;
        static unsigned int backup_msgid;
+       static struct usr_avp **backup_list;
 
        if (msg) {
-       /* remember we are back in request processing, but process
-        * a shmem-ed replica of the request; advertise it in rmode;
-        * for example t_reply needs to know that
-        */
-       backup_mode=rmode;
-       rmode=MODE_ONFAILURE;
-       /* also, tm actions look in beginning whether tranaction is
-        * set -- whether we are called from a reply-processing 
-        * or a timer process, we need to set current transaction;
-        * otherwise the actions would attempt to look the transaction
-        * up (unnecessary overhead, refcounting)
-        */
-       /* backup */
-       backup_t=get_t();
-       backup_msgid=global_msg_id;
-       /* fake transaction and message id */
+               /* remember we are back in request processing, but process
+                * a shmem-ed replica of the request; advertise it in rmode;
+                * for example t_reply needs to know that
+                */
+               backup_mode=rmode;
+               rmode=MODE_ONFAILURE;
+               /* also, tm actions look in beginning whether tranaction is
+                * set -- whether we are called from a reply-processing 
+                * or a timer process, we need to set current transaction;
+                * otherwise the actions would attempt to look the transaction
+                * up (unnecessary overhead, refcounting)
+                */
+               /* backup */
+               backup_t=get_t();
+               backup_msgid=global_msg_id;
+               /* fake transaction and message id */
                global_msg_id=msg->id;
                set_t(t);
+               /* make available the avp list from transaction */
+               backup_list = set_avp_list( &t->user_avps );
        } else {
                /* restore original environment */
                set_t(backup_t);
                global_msg_id=backup_msgid;
                rmode=backup_mode;
+               /* restore original avp list */
+               set_avp_list( backup_list );
        }
 }
 
@@ -532,33 +538,7 @@ static inline int fake_req(struct sip_msg *faked_req,
                faked_req->new_uri.s[faked_req->new_uri.len]=0;
        }
 
-#if 0
-       /* create a duplicated lump list to which actions can add
-        * new pkg items  */
-       if (shmem_msg->add_rm) {
-               faked_req->add_rm=dup_lump_list(shmem_msg->add_rm);
-               if (!faked_req->add_rm) { /* non_emty->empty ... failure */
-                       LOG(L_ERR, "ERROR: fake_req: lump dup failed\n");
-                       goto error01;
-               }
-       }
-       /* same for the body lumps */
-       if (shmem_msg->body_lumps) {
-               faked_req->body_lumps=dup_lump_list(shmem_msg->body_lumps);
-               if (!faked_req->body_lumps) { /* non_empty->empty ... failure */
-                       LOG(L_ERR, "ERROR: fake_req: lump dup failed\n");
-                       goto error02;
-               }
-       }
-#endif
        return 1;
-
-#if 0
-error02:
-       free_duped_lump_list(faked_req->add_rm);
-error01:
-       if (faked_req->new_uri.s) pkg_free(faked_req->new_uri.s);
-#endif
 error00:
        return 0;
 }
@@ -567,11 +547,6 @@ void inline static free_faked_req(struct sip_msg *faked_req, struct cell *t)
 {
        struct hdr_field *hdr;
 
-#if 0
-       free_duped_lump_list(faked_req->add_rm);
-       free_duped_lump_list(faked_req->body_lumps);
-       faked_req->add_rm = faked_req->body_lumps = 0;
-#endif
        if (faked_req->new_uri.s) {
                pkg_free(faked_req->new_uri.s);
                faked_req->new_uri.s = 0;
@@ -608,12 +583,10 @@ static inline int run_failure_handlers(struct cell *t, struct sip_msg *rpl,
 
        /* failure_route for a local UAC? */
        if (!shmem_msg) {
-               LOG(L_WARN, 
-                       "Warning: run_failure_handlers: no UAC support (%d, %d) \n",
-                       t->on_negative, 
-                       t->tmcb_hl.reg_types);
-                return 0;
-        }
+               LOG(L_WARN,"Warning: run_failure_handlers: no UAC support (%d, %d) \n",
+                       t->on_negative, t->tmcb_hl.reg_types);
+               return 0;
+       }
 
        /* don't start faking anything if we don't have to */
        if ( !has_tran_tmcbs( t, TMCB_ON_FAILURE) && !t->on_negative ) {
@@ -644,9 +617,6 @@ static inline int run_failure_handlers(struct cell *t, struct sip_msg *rpl,
                /* run a reply_route action if some was marked */
                if (run_actions(failure_rlist[on_failure], &faked_req)<0)
                        LOG(L_ERR, "ERROR: run_failure_handlers: Error in do_action\n");
-               /* destroy any eventual avps */
-               if (users_avps)
-                       destroy_avps();
        }
 
        /* restore original environment and free the fake msg */
@@ -1225,6 +1195,7 @@ int reply_received( struct sip_msg  *p_msg )
        struct ua_client *uac;
        struct cell *t;
        str next_hop;
+       struct usr_avp **backup_list;
 
        /* make sure we know the assosociated transaction ... */
        if (t_check( p_msg  , &branch )==-1)
@@ -1265,9 +1236,9 @@ int reply_received( struct sip_msg  *p_msg )
                /* acknowledge negative INVITE replies (do it before detailed
                 * on_reply processing, which may take very long, like if it
                 * is attempted to establish a TCP connection to a fail-over dst */
-
-        if (t->flags & T_IS_INVITE_FLAG) {
-                if (msg_status >= 300) {
+               
+       if (t->flags & T_IS_INVITE_FLAG) {
+               if (msg_status >= 300) {
                        ack = build_ack(p_msg, t, branch, &ack_len);
                        if (ack) {
                                SEND_PR_BUFFER(&uac->request, ack, ack_len);
@@ -1283,18 +1254,19 @@ int reply_received( struct sip_msg  *p_msg )
                        }
                }
        }
-            /* processing of on_reply block */
+       /* processing of on_reply block */
        if (t->on_reply) {
                rmode=MODE_ONREPLY;
-                    /* transfer transaction flag to message context */
+               /* transfer transaction flag to message context */
                if (t->uas.request) p_msg->flags=t->uas.request->flags;
-               if (run_actions(onreply_rlist[t->on_reply], p_msg)<0) 
+               /* set the as avp_list the one from transaction */
+               backup_list = set_avp_list( &t->user_avps );
+               if (run_actions(onreply_rlist[t->on_reply], p_msg)<0) 
                        LOG(L_ERR, "ERROR: on_reply processing failed\n");
-                    /* destroy any eventual avps */
-               if (users_avps)
-                       destroy_avps();
-                    /* transfer current message context back to t */
+               /* transfer current message context back to t */
                if (t->uas.request) t->uas.request->flags=p_msg->flags;
+               /* restore original avp list */
+               set_avp_list( backup_list );
        }
        LOCK_REPLIES( t );
        if ( is_local(t) ) {
index 5c795f4..79fd398 100644 (file)
@@ -49,6 +49,7 @@
  *              merged in transaction callbacks as LOCAL_COMPLETED (bogdan)
  *  2004-02-11  FIFO/CANCEL + alignments (hash=f(callid,cseq)) (uli+jiri)
  *  2004-02-13  t->is_invite, t->local, t->noisy_ctimer replaced (bogdan)
+ *  2004-08-23  avp support in t_uac (bogdan)
  */
 
 #include <string.h>
@@ -198,6 +199,10 @@ int t_uac(str* method, str* headers, str* body, dlg_t* dialog,
                goto error2;
        }
 
+       /* better reset avp list now - anyhow, it's useless from
+        * this point (bogdan) */
+       reset_avps();
+
        /* add the callback the the transaction for LOCAL_COMPLETED event */
        if(cb && insert_tmcb(&(new_cell->tmcb_hl),TMCB_LOCAL_COMPLETED,cb,cbp)!=1){
                ret=E_OUT_OF_MEM;
index 4c96ae5..87e4430 100644 (file)
--- a/receive.c
+++ b/receive.c
@@ -36,6 +36,7 @@
  * 2004-02-06 added user preferences support - destroy_avps() (bogdan)
  * 2004-04-30 exec_pre_cb is called after basic sanity checks (at least one
  *            via present & parsed ok)  (andrei)
+ * 2004-08-23 avp core changed - destroy_avp-> reset_avps (bogdan)
  */
 
 
@@ -57,6 +58,7 @@
 #include "dset.h"
 #include "usr_avp.h"
 
+
 #include "tcp_server.h" /* for tcpconn_add_alias */
 
 
@@ -166,10 +168,6 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
                        goto error;
                }
 
-               /* ... free posible loaded avps */
-               if (users_avps)
-                       destroy_avps();
-
 #ifdef STATS
                gettimeofday( & tve, &tz );
                diff = (tve.tv_sec-tvb.tv_sec)*1000000+(tve.tv_usec-tvb.tv_usec);
@@ -229,6 +227,8 @@ end:
 #endif
        /* execute post-script callbacks, if any; -jiri */
        exec_post_cb(msg);
+       /* free possible loaded avps -bogdan */
+       reset_avps();
        DBG("receive_msg: cleaning up\n");
        free_sip_msg(msg);
        pkg_free(msg);
@@ -240,6 +240,8 @@ error:
        DBG("error:...\n");
        /* execute post-script callbacks, if any; -jiri */
        exec_post_cb(msg);
+       /* free possible loaded avps -bogdan */
+       reset_avps();
 error02:
        free_sip_msg(msg);
        pkg_free(msg);
index d6e1b52..3a7602e 100644 (file)
--- a/usr_avp.c
+++ b/usr_avp.c
  *
  * History:
  * ---------
- *  2004-02-06  created (bogdan)
- *  2004-06-06  updated to the current DB api (andrei)
+ *  2004-07-21  created (bogdan)
  */
 
 
+#include <assert.h>
+
 #include "sr_module.h"
 #include "dprint.h"
 #include "str.h"
 #include "ut.h"
-#include "mem/mem.h"
-#include "db/db.h"
-#include "parser/parse_from.h"
-#include "parser/parse_uri.h"
+#include "mem/shm_mem.h"
 #include "usr_avp.h"
 
 
 
-static db_con_t  *avp_db_con = 0;
-static db_func_t avp_dbf; /* database call backs */
-struct usr_avp   *users_avps = 0;
-char             *avp_db_url = 0;
+struct str_int_data {
+       str  name;
+       int  val;
+};
+
+struct str_str_data {
+       str  name;
+       str  val;
+};
 
 
-static char* usr_type[] = {"ruri","from","to",0};
+static struct usr_avp *global_avps = 0;
+static struct usr_avp **crt_avps  = &global_avps;
 
 
-int init_avp_child( int rank )
+
+inline static unsigned short compute_ID( str *name )
 {
-       if ( rank>PROC_MAIN ) {
-               if (avp_db_url==0) {
-                       LOG(L_NOTICE,"NOTICE:init_avp_child: no avp_db_url specified "
-                               "-> feature disabled\n");
-                       return 0;
-               }
-               /* init db connection */
-               if ( bind_dbmod(avp_db_url, &avp_dbf) < 0 ) {
-                       LOG(L_ERR,"ERROR:init_avp_child: unable to find any db module\n");
-                       return -1;
-               }
-               if ( (avp_db_con=avp_dbf.init( avp_db_url ))==0) {
-                       /* connection failed */
-                       LOG(L_ERR,"ERROR:init_avp_child: unable to connect to database\n");
-                       return -1;
-               }
-               if (avp_dbf.use_table( avp_db_con, AVP_DB_TABLE ) < 0) {
-                       /* table selection failed */
-                       LOG(L_ERR,"ERROR:init_avp_child: unable to select db table\n");
-                       return -1;
-               }
+       char *p;
+       unsigned short id;
+
+       id=0;
+       for( p=name->s+name->len-1 ; p>=name->s ; p-- )
+               id ^= *p;
+       return id;
+}
+
+
+int add_avp(unsigned short flags, int_str name, int_str val)
+{
+       struct usr_avp *avp;
+       str *s;
+       struct str_int_data *sid;
+       struct str_str_data *ssd;
+       int len;
+
+       assert( crt_avps!=0 );
+
+       /* compute the required mem size */
+       len = sizeof(struct usr_avp);
+       if (flags&AVP_NAME_STR) {
+               if (flags&AVP_VAL_STR)
+                       len += sizeof(struct str_str_data)-sizeof(void*) + name.s->len
+                               + val.s->len;
+               else
+                       len += sizeof(struct str_int_data)-sizeof(void*) + name.s->len;
+       } else if (flags&AVP_VAL_STR)
+                       len += sizeof(str)-sizeof(void*) + val.s->len;
+
+       avp = (struct usr_avp*)shm_malloc( len );
+       if (avp==0) {
+               LOG(L_ERR,"ERROR:avp:add_avp: no more shm mem\n");
+               goto error;
+       }
+
+       avp->flags = flags;
+       avp->id = (flags&AVP_NAME_STR)? compute_ID(name.s) : name.n ;
+
+       avp->next = *crt_avps;
+       *crt_avps = avp;
+
+       switch ( flags&(AVP_NAME_STR|AVP_VAL_STR) )
+       {
+               case 0:
+                       /* avp type ID, int value */
+                       avp->data = (void*)(long)val.n;
+                       break;
+               case AVP_NAME_STR:
+                       /* avp type str, int value */
+                       sid = (struct str_int_data*)&(avp->data);
+                       sid->val = val.n;
+                       sid->name.len =name.s->len;
+                       sid->name.s = (char*)sid + sizeof(struct str_int_data);
+                       memcpy( sid->name.s , name.s->s, name.s->len);
+                       break;
+               case AVP_VAL_STR:
+                       /* avp type ID, str value */
+                       s = (str*)&(avp->data);
+                       s->len = val.s->len;
+                       s->s = (char*)s + sizeof(str);
+                       memcpy( s->s, val.s->s , s->len);
+                       break;
+               case AVP_NAME_STR|AVP_VAL_STR:
+                       /* avp type str, str value */
+                       ssd = (struct str_str_data*)&(avp->data);
+                       ssd->name.len = name.s->len;
+                       ssd->name.s = (char*)ssd + sizeof(struct str_str_data);
+                       memcpy( ssd->name.s , name.s->s, name.s->len);
+                       ssd->val.len = val.s->len;
+                       ssd->val.s = ssd->name.s + ssd->name.len;
+                       memcpy( ssd->val.s , val.s->s, val.s->len);
+                       break;
        }
 
        return 0;
+error:
+       return -1;
 }
 
 
-void print_avps(struct usr_avp *avp)
+inline static str* get_avp_name(struct usr_avp *avp)
 {
-       if (!avp)
-               return;
-       if (avp->val_type==AVP_TYPE_STR)
-               DBG("DEBUG:print_avp: %.*s=%.*s\n",
-                       avp->attr.len,avp->attr.s,
-                       avp->val.str_val.len,avp->val.str_val.s);
-       else
-               DBG("DEBUG:print_avp: %.*s=%u\n",
-                       avp->attr.len,avp->attr.s,
-                       avp->val.uint_val);
-       print_avps(avp->next);
+       switch ( avp->flags&(AVP_NAME_STR|AVP_VAL_STR) )
+       {
+               case 0:
+                       /* avp type ID, int value */
+               case AVP_VAL_STR:
+                       /* avp type ID, str value */
+                       return 0;
+               case AVP_NAME_STR:
+                       /* avp type str, int value */
+                       return &((struct str_int_data*)&avp->data)->name;
+               case AVP_NAME_STR|AVP_VAL_STR:
+                       /* avp type str, str value */
+                       return &((struct str_str_data*)&avp->data)->name;
+       }
+
+       LOG(L_ERR,"BUG:avp:get_avp_name: unknown avp type (name&val) %d\n",
+               avp->flags&(AVP_NAME_STR|AVP_VAL_STR));
+       return 0;
 }
 
 
-void destroy_avps( )
+/* get value functions */
+
+inline void get_avp_val(struct usr_avp *avp, int_str *val)
 {
-       struct usr_avp *avp;
+       if (avp==0 || val==0)
+               return;
 
-       /*print_avps(users_avps);*/
-       while (users_avps) {
-               avp = users_avps;
-               users_avps = users_avps->next;
-               pkg_free( avp );
+       switch ( avp->flags&(AVP_NAME_STR|AVP_VAL_STR) ) {
+               case 0:
+                       /* avp type ID, int value */
+                       val->n = (long)(avp->data);
+                       break;
+               case AVP_NAME_STR:
+                       /* avp type str, int value */
+                       val->n = ((struct str_int_data*)(&avp->data))->val;
+                       break;
+               case AVP_VAL_STR:
+                       /* avp type ID, str value */
+                       val->s = (str*)(&avp->data);
+                       break;
+               case AVP_NAME_STR|AVP_VAL_STR:
+                       /* avp type str, str value */
+                       val->s = &(((struct str_str_data*)(&avp->data))->val);
+                       break;
        }
 }
 
 
 
-int get_user_type( char *id )
-{
-       int i;
 
-       for(i=0;usr_type[i];i++) {
-               if (!strcasecmp( id, usr_type[i]) )
-                       return i;
-       }
+/* seach functions */
 
-       LOG(L_ERR,"ERROR:avp:get_user_type: unknown user type <%s>\n",id);
-       return -1;
+inline static struct usr_avp *internal_search_ID_avp( struct usr_avp *avp,
+                                                                                               unsigned short id)
+{
+       for( ; avp ; avp=avp->next ) {
+               if ( id==avp->id && (avp->flags&AVP_NAME_STR)==0  ) {
+                       return avp;
+               }
+       }
+       return 0;
 }
 
 
 
-inline static unsigned int compute_ID( str *attr )
+inline static struct usr_avp *internal_search_name_avp( struct usr_avp *avp,
+                                                                                               unsigned short id, str *name)
 {
-       char *p;
-       unsigned int id;
+       str * avp_name;
 
-       id=0;
-       for( p=attr->s+attr->len-1 ; p>=attr->s ; p-- )
-               id ^= *p;
-       return id;
+       for( ; avp ; avp=avp->next )
+               if ( id==avp->id && avp->flags&AVP_NAME_STR &&
+               (avp_name=get_avp_name(avp))!=0 && avp_name->len==name->len
+                && !strncasecmp( avp_name->s, name->s, name->len) ) {
+                       return avp;
+               }
+       return 0;
 }
 
 
-inline static db_res_t *do_db_query(struct sip_uri *uri,char *attr,int use_dom)
+
+struct usr_avp *search_first_avp( unsigned short name_type,
+                                                                               int_str name, int_str *val)
 {
-       static db_key_t   keys_cmp[3] = {"username","domain","attribute"};
-       static db_key_t   keys_ret[] = {"attribute","value","type"};
-       static db_val_t   vals_cmp[3];
-       unsigned int      nr_keys_cmp;
-       db_res_t          *res;
-
-       /* prepare DB query */
-       nr_keys_cmp = 0;
-       keys_cmp[ nr_keys_cmp ] = "username";
-       vals_cmp[ nr_keys_cmp ].type = DB_STR;
-       vals_cmp[ nr_keys_cmp ].nul  = 0;
-       vals_cmp[ nr_keys_cmp ].val.str_val = uri->user;
-       nr_keys_cmp++;
-       if (use_dom) {
-               keys_cmp[ nr_keys_cmp ] = "domain";
-               vals_cmp[ nr_keys_cmp ].type = DB_STR;
-               vals_cmp[ nr_keys_cmp ].nul  = 0;
-               vals_cmp[ nr_keys_cmp ].val.str_val = uri->host;
-               nr_keys_cmp++;
-       }
-       if (attr) {
-               keys_cmp[ nr_keys_cmp ] = "attribute";
-               vals_cmp[ nr_keys_cmp ].type = DB_STRING;
-               vals_cmp[ nr_keys_cmp ].nul  = 0;
-               vals_cmp[ nr_keys_cmp ].val.string_val = attr;
-               nr_keys_cmp++;
-       }
+       struct usr_avp *avp;
 
-       /* do the DB query */
-       if ( avp_dbf.query( avp_db_con, keys_cmp, 0/*op*/, vals_cmp, keys_ret,
-       nr_keys_cmp, 3, 0/*order*/, &res) < 0)
+       assert( crt_avps!=0 );
+       
+       if (*crt_avps==0)
                return 0;
 
-       return res;
+       /* search for the AVP by ID (&name) */
+       if (name_type&AVP_NAME_STR)
+               avp = internal_search_name_avp(*crt_avps,compute_ID(name.s),name.s);
+       else
+               avp = internal_search_ID_avp( *crt_avps, name.n );
+
+       /* get the value - if required */
+       if (avp && val)
+               get_avp_val(avp, val);
+
+       return avp;
 }
 
 
 
-inline static int validate_db_row(struct db_row *row, unsigned int *val_type,
-                                                                                                       unsigned int *uint_val)
+struct usr_avp *search_next_avp( struct usr_avp *avp,  int_str *val )
 {
-       /* we don't accept null values */
-       if (row->values[0].nul || row->values[1].nul || row->values[2].nul ) {
-               LOG(L_ERR,"ERROR:avp:validat_db_row: DBreply contains NULL entryes\n");
-               return -1;
-       }
-       /* check the value types */
-       if ( (row->values[0].type!=DB_STRING && row->values[0].type!=DB_STR)
-       ||  (row->values[1].type!=DB_STRING && row->values[1].type!=DB_STR)
-       || row->values[2].type!=DB_INT ) {
-               LOG(L_ERR,"ERROR:avp:validat_db_row: bad DB types in response\n");
-               return -1;
-       }
-       /* check the content of TYPE filed */
-       *val_type = (unsigned int)row->values[2].val.int_val;
-       if (*val_type!=AVP_TYPE_INT && *val_type!=AVP_TYPE_STR) {
-               LOG(L_ERR,"ERROR:avp:validat_db_row: bad val %d in type field\n",
-                       *val_type);
-               return -1;
-       }
-       /* convert from DB_STRING to DB_STR if necesary */
-       if (row->values[0].type==DB_STRING) {
-               row->values[0].val.str_val.s =  (char*)row->values[0].val.string_val;
-               row->values[0].val.str_val.len = strlen(row->values[0].val.str_val.s);
-       }
-       if (row->values[1].type==DB_STRING) {
-               row->values[1].val.str_val.s =  (char*)row->values[1].val.string_val;
-               row->values[1].val.str_val.len = strlen(row->values[1].val.str_val.s);
-       }
-       /* if type is INT decode the value */
-       if ( *val_type==AVP_TYPE_INT &&
-       str2int( &row->values[1].val.str_val, uint_val)==-1 ) {
-               LOG(L_ERR,"ERROR:avp:validat_db_row: type is INT, but value not "
-                       "<%s>\n",row->values[1].val.str_val.s);
-               return -1;
-       }
-       return 0;
-}
+       if (avp==0 || (avp=avp->next)==0)
+               return 0;
 
+       if (avp->flags&AVP_NAME_STR)
+               avp = internal_search_name_avp( avp, avp->id, get_avp_name(avp));
+       else
+               avp = internal_search_ID_avp( avp, avp->id );
 
+       if (avp && val)
+               get_avp_val(avp, val);
 
-#define copy_str(_p_,_sd_,_ss_) \
-       do {\
-               (_sd_).s = (_p_);\
-               (_sd_).len = (_ss_).len;\
-               memcpy( _p_, (_ss_).s, (_ss_).len);\
-               (_p_) += (_ss_).len;\
-       }while(0)
-/*
- * Returns:   -1 : error
- *             0 : sucess and avp(s) loaded
- *             1 : sucess but no avp loaded
- */
-int load_avp( struct sip_msg *msg, int uri_type, char *attr, int use_dom)
-{
-       db_res_t          *res;
-       struct sip_uri    uri;
-       struct usr_avp    *avp;
-       str               *uri_s;
-       int               n;
-       unsigned int      val_type;
-       unsigned int      uint_val;
-       int               len;
-       char              *p;
-
-       /* featch the user name [and domain] */
-       switch (uri_type) {
-               case 0: /* RURI */
-                       uri_s = &(msg->first_line.u.request.uri);
-                       break;
-               case 1: /* from */
-                       if (parse_from_header( msg )<0 ) {
-                               LOG(L_ERR,"ERROR:load_avp: failed to parse from\n");
-                               goto error;
-                       }
-                       uri_s = &(get_from(msg)->uri);
-                       break;
-               case 2: /* to */
-                       if (parse_headers( msg, HDR_TO, 0)<0) {
-                               LOG(L_ERR,"ERROR:load_avp: failed to parse to\n");
-                               goto error;
-                       }
-                       uri_s = &(get_to(msg)->uri);
-                       break;
-               default:
-                       LOG(L_CRIT,"BUG:load_avp: unknow username type <%d>\n",uri_type);
-                       goto error;
-       }
+       return avp;
+}
 
-       /* parse uri */
-       if (parse_uri( uri_s->s, uri_s->len , &uri )<0) {
-               LOG(L_ERR,"ERROR:load_avp: failed to parse uri\n");
-               goto error;
-       }
 
-       /* check uri */
-       if (!uri.user.s||!uri.user.len||(use_dom&&(!uri.host.len||!uri.host.s))) {
-               LOG(L_ERR,"ERROR:load_avp: uri has no user/host part <%.*s>\n",
-                       uri_s->len,uri_s->s);
-               goto error;
-       }
 
-       /* do DB query */
-       if ( (res=do_db_query( &uri, attr,use_dom))==0 ) {
-               LOG(L_ERR,"ERROR:load_avp: db_query failed\n");
-               goto error;
-       }
 
-       /* process DB response */
-       if (res->n==0) {
-               DBG("DEBUG:load_avp: no avp found for %.*s@%.*s <%s>\n",
-                       uri.user.len,uri.user.s,(use_dom!=0)*uri.host.len,uri.host.s,
-                       attr?attr:"NULL");
-               avp_dbf.free_result( avp_db_con, res);
-               /*no avp found*/
-               return 1;
-       }
+/********* free functions ********/
 
-       for( n=0 ; n<res->n ; n++) {
-               /* validate row */
-               if (validate_db_row( &res->rows[n] ,&val_type, &uint_val) < 0 )
-                       continue;
-               /* what do we have here?! */
-               DBG("DEBUG:load_avp: found avp: <%s,%s,%d>\n",
-                       res->rows[n].values[0].val.string_val,
-                       res->rows[n].values[1].val.string_val,
-               res->rows[n].values[2].val.int_val);
-               /* build a new avp struct */
-               len = sizeof(struct usr_avp);
-               len += res->rows[n].values[0].val.str_val.len ;
-               if (val_type==AVP_TYPE_STR)
-                       len += res->rows[n].values[1].val.str_val.len ;
-               avp = (struct usr_avp*)pkg_malloc( len );
-               if (avp==0) {
-                       LOG(L_ERR,"ERROR:load_avp: no more pkg mem\n");
-                       continue;
-               }
-               /* fill the structure in */
-               p = ((char*)avp) + sizeof(struct usr_avp);
-               avp->id = compute_ID( &res->rows[n].values[0].val.str_val );
-               avp->val_type = val_type;
-               /* attribute name */
-               copy_str( p, avp->attr, res->rows[n].values[0].val.str_val);
-               if (val_type==AVP_TYPE_INT) {
-                       /* INT */
-                       avp->val.uint_val = uint_val;
-               } else {
-                       /* STRING */
-                       copy_str( p, avp->val.str_val,
-                               res->rows[n].values[1].val.str_val);
+void destroy_avp( struct usr_avp *avp_del)
+{
+       struct usr_avp *avp;
+       struct usr_avp *avp_prev;
+
+       for( avp_prev=0,avp=*crt_avps ; avp ; avp_prev=avp,avp=avp->next ) {
+               if (avp==avp_del) {
+                       if (avp_prev)
+                               avp_prev->next=avp->next;
+                       else
+                               *crt_avps = avp->next;
+                       shm_free(avp);
+                       return;
                }
-               /* add avp to internal list */
-               avp->next = users_avps;
-               users_avps = avp;
        }
-
-       avp_dbf.free_result( avp_db_con, res);
-       return 0;
-error:
-       return -1;
 }
 
 
-
-inline static struct usr_avp *internal_search_avp( unsigned int id, str *attr)
+void destroy_avp_list_unsafe( struct usr_avp **list )
 {
-       struct usr_avp *avp;
+       struct usr_avp *avp, *foo;
 
-       for( avp=users_avps ; avp ; avp=avp->next )
-               if ( id==avp->id 
-               && attr->len==avp->attr.len
-               && !strncasecmp( attr->s, avp->attr.s, attr->len)
-               ) {
-                       return avp;
-               }
-       return 0;
+       avp = *list;
+       while( avp ) {
+               foo = avp;
+               avp = avp->next;
+               shm_free_unsafe( foo );
+       }
+       *list = 0;
 }
 
 
+inline void destroy_avp_list( struct usr_avp **list )
+{
+       struct usr_avp *avp, *foo;
+
+       DBG("DEBUG:destroy_avp_list: destroing list %p\n",*list);
+       avp = *list;
+       while( avp ) {
+               foo = avp;
+               avp = avp->next;
+               shm_free( foo );
+       }
+       *list = 0;
+}
 
-struct usr_avp *search_avp( str *attr)
+
+void reset_avps( )
 {
-       return internal_search_avp( compute_ID( attr ), attr);
+       assert( crt_avps!=0 );
+       
+       if ( crt_avps!=&global_avps) {
+               crt_avps = &global_avps;
+       }
+       destroy_avp_list( crt_avps );
 }
 
 
 
-struct usr_avp *search_next_avp( struct usr_avp *avp )
+struct usr_avp** set_avp_list( struct usr_avp **list )
 {
-       return internal_search_avp( avp->id, &avp->attr);
+       struct usr_avp **foo;
+       
+       assert( crt_avps!=0 );
+
+       foo = crt_avps;
+       crt_avps = list;
+       return foo;
 }
 
index e0e3fef..7fb2358 100644 (file)
--- a/usr_avp.h
+++ b/usr_avp.h
  *
  * History:
  * ---------
- *  2004-02-06  created (bogdan)
+ *  2004-07-21  created (bogdan)
  */
 
 #ifndef _SER_URS_AVP_H_
 #define _SER_URS_AVP_H_
 
 
-#include "parser/msg_parser.h"
+#include "str.h"
+
+typedef union {
+       int  n;
+       str *s;
+} int_str;
+
 
 
 struct usr_avp {
-       unsigned int id;
-       str attr;
-       unsigned int val_type;
-       union {
-               str  str_val;
-               unsigned int uint_val;
-       }val;
+       unsigned short id;
+       unsigned short flags;
        struct usr_avp *next;
+       void *data;
 };
 
-extern struct usr_avp   *users_avps;
+#define AVP_NAME_STR     (1<<0)
+#define AVP_VAL_STR      (1<<1)
 
+/* add functions */
+int add_avp( unsigned short flags, int_str name, int_str val);
 
-#define AVP_TYPE_INT     1
-#define AVP_TYPE_STR     2
 
-#define AVP_DB_TABLE     "usr_preferences"
+/* seach functions */
+struct usr_avp *search_first_avp( unsigned short name_type, int_str name,
+                                                                                                                       int_str *val );
+struct usr_avp *search_next_avp( struct usr_avp *avp, int_str *val  );
 
-#define AVP_USER_RURI    1
-#define AVP_USER_FROM    2
-#define AVP_USER_TO      3
 
-#define AVP_ALL_ATTR     ((char*)0xffffffff)
+/* free functions */
+void reset_avps( );
+void destroy_avp( struct usr_avp *avp);
+void destroy_avp_list( struct usr_avp **list );
+void destroy_avp_list_unsafe( struct usr_avp **list );
 
-/* init function */
-int init_avp_child( int rank );
-int get_user_type( char *id );
+/* get val func */
+void get_avp_val(struct usr_avp *avp, int_str *val );
+struct usr_avp** set_avp_list( struct usr_avp **list );
 
-/* load/free/seach functions */
-void destroy_avps( );
-int load_avp( struct sip_msg *msg, int type, char *attr, int use_dom);
-struct usr_avp *search_avp( str *attr);
-struct usr_avp *search_next_avp( struct usr_avp *avp );
 
 #endif