voicemail specific code added (see #define VOICE_MAIL and module vm)
authorRaphael Coeffic <rco@iptel.org>
Fri, 31 Jan 2003 13:54:59 +0000 (13:54 +0000)
committerRaphael Coeffic <rco@iptel.org>
Fri, 31 Jan 2003 13:54:59 +0000 (13:54 +0000)
Makefile.defs
modules/tm/t_lookup.c
modules/tm/t_lookup.h
modules/tm/t_reply.c
modules/tm/t_reply.h
modules/tm/tm.c
modules/tm/tm_load.c
modules/tm/tm_load.h
msg_translator.c
msg_translator.h

index 7b16876..00c628d 100644 (file)
@@ -141,6 +141,10 @@ YACC := $(shell echo "$${YACC}")
 # -DUSE_TCP
 #              compiles in tcp support (highly experimental for now, it will probably
 #              not work, use it only if you really now what you are doing)
+# -DVOICE_MAIL
+#               enables voicemail support in ser core and in tm module
+#               voicemail needs also -D_TOTAG
+
 DEFS+= -DNAME='"$(NAME)"' -DVERSION='"$(RELEASE)"' -DARCH='"$(ARCH)"' \
         -DOS='"$(OS)"' -DCOMPILER='"$(CC_VER)"' -D__CPU_$(ARCH)\
         -DCFG_DIR='"$(cfg-target)"'\
@@ -149,7 +153,8 @@ DEFS+= -DNAME='"$(NAME)"' -DVERSION='"$(RELEASE)"' -DARCH='"$(ARCH)"' \
         -DADAPTIVE_WAIT -DADAPTIVE_WAIT_LOOPS=1024 \
         -DDNS_IP_HACK \
         -DUSE_IPV6 \
-        -DDBG_QM_MALLOC \
+        -DVOICE_MAIL \
+        -D_TOTAG \
         -DUSE_TCP \
         #-DF_MALLOC \
         #-DNO_DEBUG \
index 57cad82..bc9a074 100644 (file)
@@ -930,3 +930,76 @@ int t_unref( struct sip_msg* p_msg  )
        return 1;
 }
 
+#ifdef VOICE_MAIL
+int t_get_trans_ident(struct sip_msg* p_msg, unsigned int* hash_index, unsigned int* label)
+{
+    struct cell* t;
+    if(t_check(p_msg,0) != 1){
+       LOG(L_ERR,"ERROR: t_get_trans_ident: no transaction found\n");
+       return -1;
+    }
+    t = get_t();
+    if(!t){
+       LOG(L_ERR,"ERROR: t_get_trans_ident: transaction found is NULL\n");
+       return -1;
+    }
+    
+    *hash_index = t->hash_index;
+    *label = t->label;
+
+    return 1;
+}
+
+int t_lookup_ident(struct sip_msg** p_msg, unsigned int hash_index, unsigned int label)
+{
+    int ret = 0;
+    struct cell* p_cell;
+
+    if(hash_index >= TABLE_ENTRIES){
+       LOG(L_ERR,"ERROR: t_lookup_ident: invalid hash_index=%u\n",hash_index);
+       return -1;
+    }
+
+    LOCK_HASH(hash_index);
+
+    /* all the transactions from the entry are compared */
+    for ( p_cell = get_tm_table()->entrys[hash_index].first_cell;
+         p_cell; p_cell = p_cell->next_cell ) 
+    {
+       if(p_cell->label == label){
+           ret = 1;
+           break;
+       }
+    }
+
+    if(ret==1){
+       DBG("DEBUG: t_lookup_ident: transaction found\n");
+       *p_msg = p_cell->uas.request;
+    }
+    else
+       DBG("DEBUG: t_lookup_ident: transaction not found\n");
+    
+    UNLOCK_HASH(hash_index);
+    return ret;
+}
+
+int t_is_local(struct sip_msg* p_msg)
+{
+    struct cell* t;
+    if(t_check(p_msg,0) != 1){
+       LOG(L_ERR,"ERROR: t_is_local: no transaction found\n");
+       return -1;
+    }
+    t = get_t();
+    if(!t){
+       LOG(L_ERR,"ERROR: t_is_local: transaction found is NULL\n");
+       return -1;
+    }
+    
+    return t->local;
+}
+
+#endif
+
+
+
index 31ab17e..a59b7a2 100644 (file)
@@ -73,6 +73,20 @@ struct cell *get_t();
  * primarily set by lookup functions */
 void set_t(struct cell *t);
 
+#ifdef VOICE_MAIL
+
+#define T_GET_TI       "t_get_trans_ident"
+#define T_LOOKUP_IDENT "t_lookup_ident"
+#define T_IS_LOCAL     "t_is_local"
+
+typedef int (*tislocal_f)(struct sip_msg*);
+typedef int (*tget_ti_f)(struct sip_msg*, unsigned int*, unsigned int*);
+typedef int (*tlookup_ident_f)(struct sip_msg**, unsigned int, unsigned int);
+
+int t_is_local(struct sip_msg*);
+int t_get_trans_ident(struct sip_msg* p_msg, unsigned int* hash_index, unsigned int* label);
+int t_lookup_ident(struct sip_msg** p_msg, unsigned int hash_index, unsigned int label);
+#endif
 
 #endif
 
index b0db11f..879ef1b 100644 (file)
@@ -491,6 +491,18 @@ error:
 }
 
 
+#ifdef VOICE_MAIL
+static int _reply_light( struct cell *trans, char* buf, unsigned int len,
+                        unsigned int code, char * text, 
+                        char *to_tag, unsigned int to_tag_len, int lock );
+
+int t_reply_light( struct cell *t, char* buf, unsigned int len,
+                  unsigned int code, char * text,
+                  char *to_tag, unsigned int to_tag_len )
+{
+    return _reply_light( t, buf, len, code, text, to_tag, to_tag_len, 1 /* lock replies */ );
+}
+#endif
 
 int t_reply( struct cell *t, struct sip_msg* p_msg, unsigned int code, 
        char * text )
@@ -512,18 +524,25 @@ int t_reply_unsafe( struct cell *t, struct sip_msg* p_msg, unsigned int code,
 static int _reply( struct cell *trans, struct sip_msg* p_msg, 
        unsigned int code, char * text, int lock )
 {
+#ifndef VOICE_MAIL
        unsigned int len, buf_len=0;
        char * buf;
        struct retr_buf *rb;
 
        branch_bm_t cancel_bitmap;
+#else
+       unsigned int len;
+       char * buf;
+#endif
 
        if (code>=200) trans->kr|=REQ_RPLD;
        /*
        buf = build_res_buf_from_sip_req(code,text,trans->uas.tag->s,
                trans->uas.tag->len, trans->uas.request,&len);
        */
+#ifndef VOICE_MAIL
        cancel_bitmap=0;
+#endif
        /* compute the buffer in private memory prior to entering lock;
         * create to-tag if needed */
        if (code>=180 && p_msg->to 
@@ -533,11 +552,34 @@ static int _reply( struct cell *trans, struct sip_msg* p_msg,
                buf = build_res_buf_from_sip_req(code,text, 
                                tm_tags, TOTAG_LEN, 
                                p_msg,&len);
+#ifdef VOICE_MAIL
+
+               return _reply_light(trans,buf,len,code,text,
+                                   tm_tags, TOTAG_LEN,
+                                   lock);
+#endif
        } else {
                buf = build_res_buf_from_sip_req(code,text, 0,0, /* no to-tag */
                        p_msg,&len);
+#ifdef VOICE_MAIL
+
+               return _reply_light(trans,buf,len,code,text,
+                                   0,0, /* no to-tag */
+                                   lock);
+#endif
        }
        DBG("DEBUG: t_reply: buffer computed\n");
+#ifdef VOICE_MAIL
+}
+
+static int _reply_light( struct cell *trans, char* buf, unsigned int len,
+                        unsigned int code, char * text, 
+                        char *to_tag, unsigned int to_tag_len, int lock )
+{
+       struct retr_buf *rb;
+       unsigned int buf_len=0;
+       branch_bm_t cancel_bitmap=0;
+#endif
        if (!buf)
        {
                DBG("DEBUG: t_reply: response building failed\n");
@@ -571,6 +613,19 @@ static int _reply( struct cell *trans, struct sip_msg* p_msg,
        }
        rb->buffer_len = len ;
        memcpy( rb->buffer , buf , len );
+#ifdef VOICE_MAIL
+       if(to_tag){
+           trans->uas.to_tag.s = (char*)shm_resize( trans->uas.to_tag.s, to_tag_len );
+           if(! trans->uas.to_tag.s ){
+                       LOG(L_ERR, "ERROR: t_reply: cannot allocate shmem buffer\n");
+                       // Is it ok? or should i free rb->buffer also, 
+                       // or will it be freed in free_cell() ?
+                       goto error2; 
+           }
+           trans->uas.to_tag.len = to_tag_len;
+           memcpy( trans->uas.to_tag.s, to_tag, to_tag_len );
+       }
+#endif
        /* needs to be protected too because what timers are set depends
           on current transactions status */
        /* t_update_timers_after_sending_reply( rb ); */
@@ -1027,3 +1082,55 @@ done:
        return 0;
 }
 
+#ifdef VOICE_MAIL
+
+#include <assert.h>
+
+int t_reply_with_body( struct sip_msg* p_msg, unsigned int code, char * text, char * body, char * new_header, char * to_tag )
+{
+    struct cell * t;
+    //char to_tag[64];
+    str  s_to_tag,sb,snh;
+    char* res_buf;
+    int res_len,ret;
+
+    /*  check if we have a transaction */
+    if (t_check(p_msg, 0)==-1) {
+       LOG(L_ERR,"ERROR: t_reply_with_body: no transaction found.\n");
+       return -1;
+    }
+
+    t=get_t();
+    assert(t);
+
+    s_to_tag.s = to_tag;
+    if(to_tag)
+       s_to_tag.len = strlen(to_tag);
+
+    // mark the transaction as replied
+    t->kr|=REQ_RPLD;
+
+    /* compute the response */
+    sb.s = body;
+    sb.len = strlen(body);
+    snh.s = new_header;
+    snh.len = strlen(new_header);
+
+    res_buf = build_res_buf_with_body_from_sip_req(code,text, s_to_tag.s, s_to_tag.len,
+                                                  sb.s,sb.len,
+                                                  snh.s,snh.len,
+                                                  p_msg,&res_len);
+    
+    DBG("t_reply_with_body: buffer computed\n");
+    // frees 'res_buf' ... no panic !
+    ret = t_reply_light(t, res_buf, res_len, code, text,
+                       s_to_tag.s, s_to_tag.len);
+
+    // TODO: i'm not sure i should do this here ...
+    if(t_unref(p_msg) == -1)
+       LOG(L_WARN,"WARNING: fifo_t_reply: could not unref transaction %p\n",t);
+
+    return ret;
+}
+
+#endif
index acec7a3..5d80b76 100644 (file)
@@ -60,6 +60,11 @@ typedef unsigned int branch_bm_t;
 /* reply export types */
 typedef int (*treply_f)( struct sip_msg* p_msg,
        unsigned int code, char * text );
+#ifdef VOICE_MAIL
+typedef int (*treply_wb_f)( struct sip_msg* p_msg,
+       unsigned int code, char * text, char * body, 
+       char * new_header, char * to_tag);
+#endif
 
 #define LOCK_REPLIES(_t) lock(&(_t)->reply_mutex )
 #define UNLOCK_REPLIES(_t) unlock(&(_t)->reply_mutex )
@@ -79,6 +84,21 @@ int t_on_reply( struct sip_msg  *p_msg ) ;
 int t_retransmit_reply( /* struct sip_msg * */  );
 
 
+/* send a UAS reply
+ * Warning: 'buf' and 'len' should already have been build.
+ * returns 1 if everything was OK or -1 for erro
+ */
+#ifdef VOICE_MAIL
+
+int t_reply_light( struct cell *trans, char* buf, unsigned int len,
+                  unsigned int code, char * text,
+                  char *to_tag, unsigned int to_tag_len);
+
+int t_reply_with_body( struct sip_msg* p_msg, unsigned int code, 
+                      char * text, char * body, char * new_header, char * to_tag );
+
+#endif
+
 /* send a UAS reply
  * returns 1 if everything was OK or -1 for erro
  */
index 174279e..60ac37f 100644 (file)
@@ -137,6 +137,12 @@ struct module_exports exports= {
 #endif
                                T_UAC_DLG,
                                "load_tm",
+#ifdef VOICE_MAIL
+                               T_REPLY_WB,
+                               T_IS_LOCAL,
+                               T_GET_TI,
+                               T_LOOKUP_IDENT,
+#endif
                                "t_newdlg"
                        },
        (cmd_function[]){
@@ -160,6 +166,12 @@ struct module_exports exports= {
 #endif
                                        (cmd_function) t_uac_dlg,
                                        (cmd_function) load_tm,
+#ifdef VOICE_MAIL
+                                       (cmd_function) t_reply_with_body,
+                                       (cmd_function) t_is_local,
+                                       (cmd_function) t_get_trans_ident,
+                                       (cmd_function) t_lookup_ident,
+#endif
                                        w_t_newdlg,
                                        },
        (int[]){
@@ -182,6 +194,12 @@ struct module_exports exports= {
 #endif
                                NO_SCRIPT /* t_uac_dlg */,
                                NO_SCRIPT /* load_tm */,
+#ifdef VOICE_MAIL
+                               NO_SCRIPT /* t_reply_with_body */,
+                               NO_SCRIPT /* t_is_local */,
+                               NO_SCRIPT /* t_get_trans_ident */,
+                               NO_SCRIPT /* t_lookup_ident */,
+#endif
                                0 /* t_newdlg */
                        },
        (fixup_function[]){
@@ -204,6 +222,12 @@ struct module_exports exports= {
 #endif
                                0,                                              /* t_uac_dlg */
                                0,                                              /* load_tm */
+#ifdef VOICE_MAIL
+                               0, /* t_reply_with_body */
+                               0, /* t_is_local */
+                               0, /* t_get_trans_ident */
+                               0, /* t_lookup_ident */
+#endif
                                0                                               /* t_newdlg */
        
                },
@@ -211,10 +235,12 @@ struct module_exports exports= {
        1+
 #endif
 #ifdef _OBSO
-       15,
-#else
-       14,
+       1+
 #endif
+#ifdef VOICE_MAIL
+       4+
+#endif
+       14,
 
        /* ------------ exported variables ---------- */
        (char *[]) { /* Module parameter names */
index 5245763..79fda3e 100644 (file)
@@ -63,6 +63,24 @@ int load_tm( struct tm_binds *tmb)
                LOG( L_ERR, LOAD_ERROR "'t_reply' not found\n");
                return -1;
        }
+#ifdef VOICE_MAIL
+       if (!(tmb->t_reply_with_body=(treply_wb_f)find_export(T_REPLY_WB, NO_SCRIPT)) ) {
+               LOG( L_ERR, LOAD_ERROR "'t_reply' not found\n");
+               return -1;
+       }
+       if (!(tmb->t_is_local=(tget_ti_f)find_export(T_IS_LOCAL, NO_SCRIPT)) ) {
+               LOG( L_ERR, LOAD_ERROR "'t_get_trans_ident' not found\n");
+               return -1;
+       }
+       if (!(tmb->t_get_trans_ident=(tget_ti_f)find_export(T_GET_TI, NO_SCRIPT)) ) {
+               LOG( L_ERR, LOAD_ERROR "'t_get_trans_ident' not found\n");
+               return -1;
+       }
+       if (!(tmb->t_lookup_ident=(tlookup_ident_f)find_export(T_LOOKUP_IDENT, NO_SCRIPT)) ) {
+               LOG( L_ERR, LOAD_ERROR "'t_lookup_ident' not found\n");
+               return -1;
+       }
+#endif
 #ifdef _OBSO
        if (!(tmb->t_reply_unsafe=(treply_f)find_export(T_REPLY_UNSAFE, 2)) ) {
                LOG( L_ERR, LOAD_ERROR "'t_reply_unsafe' not found\n");
index c07c331..948962f 100644 (file)
@@ -37,6 +37,9 @@
 #include "uac.h"
 #include "t_fwd.h"
 #include "t_reply.h"
+#ifdef VOICE_MAIL
+#    include "t_lookup.h"
+#endif
 
 /* export not usable from scripts */
 #define NO_SCRIPT      -1
@@ -48,6 +51,9 @@
 #endif
 #define T_UAC_DLG "t_uac_dlg"
 #define T_REPLY "t_reply"
+#ifdef VOICE_MAIL
+#define T_REPLY_WB "t_reply_with_body"
+#endif
 #define T_REPLY_UNSAFE "t_reply_unsafe"
 #define T_FORWARD_NONACK "t_forward_nonack"
 
@@ -62,6 +68,12 @@ struct tm_binds {
 #endif
        tuacdlg_f               t_uac_dlg;
        treply_f                t_reply;
+#ifdef VOICE_MAIL
+        treply_wb_f             t_reply_with_body;
+        tislocal_f              t_is_local;
+        tget_ti_f               t_get_trans_ident;
+        tlookup_ident_f         t_lookup_ident;
+#endif
        treply_f                t_reply_unsafe;
        tfwd_f                  t_forward_nonack;
 };
index 1bb833b..addfe3b 100644 (file)
@@ -814,6 +814,20 @@ error:
 char * build_res_buf_from_sip_req( unsigned int code, char *text,
                                        char *new_tag, unsigned int new_tag_len,
                                        struct sip_msg* msg, unsigned int *returned_len)
+#ifdef VOICE_MAIL
+{
+    return build_res_buf_with_body_from_sip_req(code,text,new_tag,new_tag_len,
+                                               0,0, /* no body */
+                                               0,0, /* no content type */
+                                               msg,returned_len);
+}
+
+char * build_res_buf_with_body_from_sip_req( unsigned int code, char *text ,
+                                            char *new_tag, unsigned int new_tag_len ,
+                                            char *body, unsigned int body_len,
+                                            char *content_type, unsigned int content_type_len,
+                                            struct sip_msg* msg, unsigned int *returned_len)
+#endif
 {
        char              *buf, *p;
        unsigned int      len,foo;
@@ -830,6 +844,10 @@ char * build_res_buf_from_sip_req( unsigned int code, char *text,
        unsigned int      warning_len;
        unsigned int      text_len;
        int r;
+#ifdef VOICE_MAIL
+       char content_len[27];
+       int content_len_len;
+#endif
 #ifndef PRESERVE_ZT
        char *after_body;
 #endif
@@ -928,9 +946,17 @@ char * build_res_buf_from_sip_req( unsigned int code, char *text,
        if (server_signature) {
                /*server header*/
                len += SERVER_HDR_LEN + CRLF_LEN;
+#ifndef VOICE_MAIL
                /*content length header*/
                len +=CONTENT_LENGTH_LEN+1 + CRLF_LEN;
+#endif
        }
+#ifdef VOICE_MAIL
+       content_len_len=snprintf(content_len, sizeof(content_len), "Content-Length: %d", body_len);
+       len += content_len_len + CRLF_LEN;
+       if(content_type_len)
+           len += content_type_len + CRLF_LEN;
+#endif
        if (sip_warning) {
                warning = warning_builder(msg,&warning_len);
                if (warning) len += warning_len + CRLF_LEN;
@@ -938,6 +964,11 @@ char * build_res_buf_from_sip_req( unsigned int code, char *text,
        }
        /* end of message */
        len += CRLF_LEN; /*new line*/
+
+#ifdef VOICE_MAIL
+       if(body_len)
+           len += body_len;
+#endif
        /*allocating mem*/
        buf = (char*) pkg_malloc( len+1 );
        if (!buf)
@@ -1062,12 +1093,27 @@ char * build_res_buf_from_sip_req( unsigned int code, char *text,
                p+=SERVER_HDR_LEN;
                memcpy( p, CRLF, CRLF_LEN );
                p+=CRLF_LEN;
+#ifndef VOICE_MAIL
                /* content length header*/
                memcpy( p, CONTENT_LENGTH "0" , CONTENT_LENGTH_LEN+1 );
                p+=CONTENT_LENGTH_LEN+1;
                memcpy( p, CRLF, CRLF_LEN );
                p+=CRLF_LEN;
+#endif
+       }
+
+#ifdef VOICE_MAIL
+       memcpy( p, content_len, content_len_len );
+       p+=content_len_len;
+       memcpy( p, CRLF, CRLF_LEN );
+       p+=CRLF_LEN;
+       if(content_type_len){
+           memcpy( p, content_type, content_type_len );
+           p+=content_type_len;
+           memcpy( p, CRLF, CRLF_LEN );
+           p+=CRLF_LEN;
        }
+#endif
        if (sip_warning && warning) {
                memcpy( p, warning, warning_len);
                p+=warning_len;
@@ -1077,6 +1123,12 @@ char * build_res_buf_from_sip_req( unsigned int code, char *text,
        /*end of message*/
        memcpy( p, CRLF, CRLF_LEN );
        p+=CRLF_LEN;
+#ifdef VOICE_MAIL
+       if(body_len){
+           memcpy ( p, body, body_len );
+           p+=body_len;
+       }
+#endif
        *(p) = 0;
        *returned_len = len;
        /* in req2reply, received_buf is not introduced to lumps and
index c4c7b79..7f37b3b 100644 (file)
@@ -54,6 +54,18 @@ char * build_res_buf_from_sip_req(   unsigned int code ,
                                unsigned int new_tag_len ,
                                struct sip_msg* msg,
                                unsigned int *returned_len);
+#ifdef VOICE_MAIL
+char * build_res_buf_with_body_from_sip_req(   unsigned int code ,
+                               char *text ,
+                               char *new_tag ,
+                               unsigned int new_tag_len ,
+                               char *body ,
+                               unsigned int body_len,
+                               char *content_type,
+                               unsigned int content_type_len,
+                               struct sip_msg* msg,
+                               unsigned int *returned_len);
+#endif
 
 char* via_builder( unsigned int *len,
        struct socket_info* send_sock,