Hi there,
I have problem in loading module TM for voicemail setup here.
I use SER 0.9.7 as server and the latest SEMS for voicemail usage.
I tried to add my ser.cfg with script that can handle the voicemail but I found errors when run SER.
Below is my ser.cfg: (Please take a look at line 54 and 56)

debug=9
fork=yes
log_stderror=yes

listen=202.95.149.2       # put your server IP address here
port=5060
children=4

dns=no
rev_dns=no

fifo="/tmp/ser_fifo"
fifo_db_url="mysql://ser:heslo@localhost/ser"
fifo_mode=0666
unix_sock="/tmp/ser_sock"

loadmodule "/usr/local/lib/ser/modules/mysql.so"
loadmodule "/usr/local/lib/ser/modules/sl.so"
loadmodule "/usr/local/lib/ser/modules/tm.so"
loadmodule "/usr/local/lib/ser/modules/rr.so"
loadmodule "/usr/local/lib/ser/modules/maxfwd.so"
loadmodule "/usr/local/lib/ser/modules/usrloc.so"
loadmodule "/usr/local/lib/ser/modules/registrar.so"
loadmodule "/usr/local/lib/ser/modules/auth.so"
loadmodule "/usr/local/lib/ser/modules/auth_db.so"
loadmodule "/usr/local/lib/ser/modules/nathelper.so"
loadmodule "/usr/local/lib/ser/modules/textops.so"
loadmodule "/usr/local/lib/ser/modules/uri_db.so"
loadmodule "/usr/local/lib/ser/modules/uri.so"
loadmodule "/usr/local/lib/ser/modules/avp.so"
loadmodule "/usr/local/lib/ser/modules/avpops.so"
loadmodule "/usr/local/lib/ser/modules/domain.so"
loadmodule "/usr/local/lib/ser/modules/permissions.so"
loadmodule "/usr/local/lib/ser/modules/msilo.so"

modparam("auth_db|permissions|uri_db|usrloc","db_url", "mysql://ser:heslo@localhost/ser")
modparam("auth_db|uri_db|usrloc", "db_url", "mysql://ser:heslo@localhost/ser")
modparam("auth_db", "calculate_ha1", 1)
modparam("auth_db", "password_column", "password")

modparam("nathelper", "natping_interval", 30)
modparam("nathelper", "ping_nated_only", 1)
modparam("nathelper", "rtpproxy_sock", "/var/run/rtpproxy.sock")

modparam("usrloc", "db_mode", 2)

modparam("registrar", "nat_flag", 6)

modparam("rr", "enable_full_lr", 1)

modparam("tm", "fr_inv_timer", 27)
modparam("tm", "fr_inv_timer_avp", "inv_timeout")                                                                            modparam("tm", "fr_timer", 10 )
modparam("tm", "wt_timer", 10 )
line 54: modparam("tm", "pass_provisional_replies", 1)
# configure tm to append this when tw_appent voicemail_headers is used
line 56: modparam("tm", "tw_append","voicemail_headers:P-Email-Address=avp[$email]")
# appends for dtmf per INFO
modparam( "tm", "tw_append","info_append:hdr[Content-Length];hdr[Content-Type];msg[body]")

modparam("permissions", "db_mode", 1)
modparam("permissions", "trusted_table", "trusted")

modparam("msilo", "db_url", "mysql://ser:heslo@localhost/ser")
modparam("msilo", "db_table", "silo")
modparam("msilo","registrar","sip:registrar@pcr.ac.id")
modparam("msilo","expire_time",259200)
modparam("msilo","check_time",30)
modparam("msilo","clean_period",5)

# configure avpops db connection
modparam( "avpops", "avp_url", "mysql://ser:heslo@localhost/ser" )
modparam( "avpops", "avp_table", "subscriber" )
modparam( "avpops", "uuid_column", "id" )

# configure aliases, the number doesn't matter as long as there are no collisions)
modparam( "avpops", "avp_aliases", "email=i:67" )

# scheme to access the database
modparam( "avpops", "db_scheme",
        "email_scheme:table=subscriber;value_col=email_address;value_type=string")
#modparam( "avpops", "db_scheme",
#       "language_scheme:table=subscriber;value_col=language;value_type=string")

alias="pcr.ac.id"
route {
        # -----------------------------------------------------------------
        # Sanity Check Section
        # -----------------------------------------------------------------

        if (!mf_process_maxfwd_header("10")) {
                sl_send_reply("483", "Too Many Hops");
                break;
        };

        if (msg:len > max_len) {
                sl_send_reply("513", "Message Overflow");
                break;
        };
      /*
      if (method != "ACK" && method != "INVITE" && method != "BYE"
            && method != "CANCEL" && method != "INFO" ){
                  log("unsupported method\n");
                  sl_send_reply("500","unsupported method");
                  break;
      }
      */

      # make transaction
      if (!t_newtran()){
            log("could not create transaction\n");
            sl_send_reply("500","could not create transaction");
            break;
      }

      # actively absorb ACKs
      if (method == "ACK") {
            t_relay();
            break;
      }
     
      # pass INFO to SEMS
      if (method=="INFO") {
            if(!t_write_unix("/tmp/sems_sock","sems/info_append")){
                        log("could not contact sems\n");
                        t_reply("500","could not contact media server");
            }
      }

      if (uri =~ "sip:101.*@") {
            if (!t_write_unix("/tmp/sems_sock","myapp")){
                  log("could not contact media server\n");
                  t_reply("500","could not contact media server");     
                  break;
            }
            break;
      }

      if (uri =~ "sip:102.*@") {
            if (!t_write_unix("/tmp/sems_sock","myconfigurableapp")){
                  log("could not contact media server\n");
                  t_reply("500","could not contact media server");     
                  break;
            }
            break;
      }

      if (uri =~ "sip:103.*@") {
            if (!t_write_unix("/tmp/sems_sock","myannounceapp")){
                  log("could not contact media server\n");
                  t_reply("500","could not contact media server");     
                  break;
            }
            break;
      }

      if (uri =~ "sip:104.*@") {
            if (!t_write_unix("/tmp/sems_sock","myjukebox")){
                  log("could not contact media server\n");
                  t_reply("500","could not contact media server");     
                  break;
            }
            break;
      }

      if (uri =~ "sip:105.*@") {
            if (!t_write_unix("/tmp/sems_sock","mycc")){
                  log("could not contact media server\n");
                  t_reply("500","could not contact media server");     
                  break;
            }
            break;
      }

      if (uri =~ "sip:106.*@") {
            if (!t_write_unix("/tmp/sems_sock","ivr_announce")){
                  log("could not contact media server\n");
                  t_reply("500","could not contact media server");     
                  break;
            }
            break;
      }

############ default sems apps
      if (uri =~ "sip:110.*@") {
            if (!t_write_unix("/tmp/sems_sock","echo")){
                  log("could not contact echo\n");
                  t_reply("500","could not contact media server");     
                  break;
            }
            break;
      }


      if (uri =~ "sip:111.*@") {
            if (!t_write_unix("/tmp/sems_sock","announcement")){
                  log("could not contact announcement\n");
                  t_reply("500","could not contact media server");     
                  break;
            }
            break;
      }

      if (uri =~ "sip:112.*@") {
            if (!t_write_unix("/tmp/sems_sock","conference")){
                  log("could not contact conference\n");
                  t_reply("500","could not contact media server");     
                  break;
            }
            break;
      }


      if (uri =~ "sip:113.*@") {
            if (!t_write_unix("/tmp/sems_sock","mailbox")){
                  log("could not contact mailbox\n");
                  t_reply("500","could not contact media server");     
                  break;
            }
            break;
      }

      if (uri =~ "sip:114.*@") {
            if (!t_write_unix("/tmp/sems_sock","early_announce")){
                  log("could not contact early_announce\n");
                  t_reply("500","could not contact media server");     
                  break;
            }
            break;
      }

      if (uri =~ "sip:115.*@") {
            # load email avp with some email address
            avp_write("root@localhost","$email");
            # use voicemail_headers append to pass it to sems
            if (!t_write_unix("/tmp/sems_sock","voicemail/voicemail_headers")){
                  log("could not contact voicemail\n");
                  t_reply("500","could not contact media server");     
                  break;
            }
            break;
      }
      t_reply("404","Not found");

        # -----------------------------------------------------------------
        # Record Route Section
        # -----------------------------------------------------------------

        if (method!="REGISTER") {
                record_route();
        };

        if (method=="BYE" || method=="CANCEL") {
                unforce_rtp_proxy();
        }

        # -----------------------------------------------------------------
        # Loose Route Section
        # -----------------------------------------------------------------

        if (loose_route()) {
                if (has_totag() && (method=="INVITE" || method=="ACK")) {
                        if (nat_uac_test("19")) {
                                setflag(6);
                                force_rport();
                                fix_nated_contact();
                        };
                    force_rtp_proxy("l");
                };
                route(1);
                break;
        };

        # -----------------------------------------------------------------
        # Offline Message Store Section
        # -----------------------------------------------------------------
      if (is_from_local()) {  
            if (method=="REGISTER") {
            save("location");
            log("REGISTER received -> dumping messages with MSILO\n");

            # MSILO - dumping user's offline messages
            if (m_dump())
            {
                log("MSILO: offline messages dumped - if they were\n");
            }else{
                log("MSILO: no offline messages dumped\n");
            };
            break;
        };

        # domestic SIP destinations are handled using our USRLOC DB

        if(!lookup("location"))
        {
            if (! t_newtran())
               {
                sl_reply_error();
                break;
               };
            # we do not care about anything else but MESSAGEs
            if (!method=="MESSAGE")
            {
                if (!t_reply("404", "Not found"))
                {
                    sl_reply_error();
                };
                break;
            };
            log("MESSAGE received -> storing using MSILO\n");
            # MSILO - storing as offline message
            if (m_store("0"))
            {
                log("MSILO: offline message stored\n");
                if (!t_reply("202", "Accepted"))
                {
                    sl_reply_error();
                };
            }else{
                log("MSILO: offline message NOT stored\n");
                if (!t_reply("503", "Service Unavailable"))
                {
                    sl_reply_error();
                };
            };
            break;
        };
        # if the downstream UA does not support MESSAGE requests
        # go to failure_route[1]
        t_on_failure("1");
        t_relay();
        break;
    };
      # forward to current uri now; use stateful forwarding that
        # works reliably even if we forward from TCP to UDP
        if (!t_relay()) {
                sl_reply_error();
        };

       # -----------------------------------------------------------------
        # Call Type Processing Section
        # -----------------------------------------------------------------

        if (uri!=myself) {
                        route(5);
                        route(1);
                        break;
        };

        if (uri==myself) {
                if (method=="ACK") {
                        route(6);
                        break;
                } else if (method=="CANCEL") {
                        route(3);
                        break;
                } else if (method=="INVITE") {
                        route(3);
                        break;
                } else  if (method=="REGISTER") {
                        route(2);
                        break;
                };
                lookup("aliases");
                if (uri!=myself) {
                        route(5);
                        route(1);
                        break;
                };

                if (!lookup("location")) {
                        sl_send_reply("404", "User Not Found");
                        break;
                };
        };
        route(1);
}

failure_route[1] {
    # forwarding failed -- check if the request was a MESSAGE
    if (!method=="MESSAGE")
    {
        break;
    };

    log(1,"MSILO:the downstream UA doesn't support MESSAGEs\n");
    # we have changed the R-URI with the contact address, ignore it now
    if (m_store("1"))
    {
        log("MSILO: offline message stored\n");
        t_reply("202", "Accepted");
    }else{
        log("MSILO: offline message NOT stored\n");
        t_reply("503", "Service Unavailable");
    };
}

route[1] {

        # -----------------------------------------------------------------
        # Default Message Handler
        # -----------------------------------------------------------------

        t_on_reply("1");
        if (!t_relay()) {
                if (method=="INVITE" && isflagset(6)) {
                  unforce_rtp_proxy();
                };
                sl_reply_error();
        };
}

route[2] {

        # -----------------------------------------------------------------
        # REGISTER Message Handler
        # ----------------------------------------------------------------

        if (!search("^Contact:\ +\*") && nat_uac_test("19")) {
                setflag(6);
                fix_nated_register();
                force_rport();
        };
        sl_send_reply("100", "Trying");

        if (!www_authorize("pcr.ac.id","subscriber")) {
                www_challenge("pcr.ac.id","0");
                break;
        };

        if (!check_to()) {
                sl_send_reply("401", "Unauthorized");
                break;
        };
        consume_credentials();
        if (!save("location")) {
                sl_reply_error();
        };
}

route[3] {

        # -----------------------------------------------------------------
        # CANCEL and INVITE Message Handler
        # -----------------------------------------------------------------

        if (!allow_trusted() && nat_uac_test("19")) {
                 setflag(6);
        }
        lookup("aliases");
        if (method=="INVITE" && !allow_trusted())
        {
                if (!proxy_authorize("pcr.ac.id","subscriber")) {
                        proxy_challenge("pcr.ac.id","0");
                        break;
                } else if (!check_from()) {
                        sl_send_reply("403", "Use From=ID");
                        break;
                };
                consume_credentials();
        };

        if (uri=~"^sip:9[0-9]*@") {
                route(4);
                break;
        };

        if (uri!=myself) {
                route(5);
                route(1);
                break;
        };

        if (!lookup("location")) {
                if (uri=~"^sip:[0-9]{10}@") {
                route(4);
                break;
                };
                sl_send_reply("404", "User Not Found");
                break;
        };

        if (isflagset(6)) {
                force_rport();
                fix_nated_contact();
                force_rtp_proxy();
        };
        t_on_reply("1");

        if (!t_relay()) {
                if(isflagset(6)) {
                        unforce_rtp_proxy();
                }
                sl_reply_error();
        };
}

route[4] {

 # -----------------------------------------------------------------
 # PSTN Handler
 # -----------------------------------------------------------------

 rewritehostport("202.95.149.2:5060"); # INSERT YOUR PSTN GATEWAY IP ADDRESS
 avp_write("i:45", "inv_timeout");

 if (isflagset(6)) {
                force_rport();
                fix_nated_contact();
                force_rtp_proxy();
                };
 route(1);
 }

onreply_route[1] {
        if (isflagset(6) && status=~"(180)|(183)|2[0-9][0-9]") {
                if (!search("^Content-Length:\ +0")) {
                        force_rtp_proxy();
                };
        };

        if (nat_uac_test("1")) {
                fix_nated_contact();
        };
}
--------------------------------------------------------------------------------------------------------------------
 If I uncomment line 54 and 56, below is the output when I run SER:
0(4425) set_mod_param_regex: parameter <pass_provisional_replies> not found in module <tm>
 0(4425) parse error (54,19-20): Can't set module parameter
 0(4425) set_mod_param_regex: tm matches module tm
 0(4425) set_mod_param_regex: found <tw_append> in module tm [/usr/local/lib/ser/modules/tm.so]
 0(4425) ERROR:tm:parse_tw_append: bad alias spec <$email>
 0(4425) parse error (56,19-20): Can't set module parameter
 0(4425) set_mod_param_regex: tm matches module tm
-----------------------------------------------------------------------------------------------------------------------
If I comment line 54 and 56, below is the output:
 0(0) ERROR:tm:fixup_t_write: unknown append name <voicemail_headers>
 0(0) ERROR: fix_expr : fix_actions error
ERROR: error -6 while trying to fix configuration
 0(0) MSILO: destroy module ...
 0(0) DEBUG: tm_shutdown : start
 0(0) DEBUG: unlink_timer_lists : emptying DELETE list
 0(0) DEBUG: tm_shutdown : emptying hash table
 0(0) DEBUG: tm_shutdown : releasing timers
 0(0) DEBUG: tm_shutdown : removing semaphores
 0(0) DEBUG: tm_shutdown : destroying tmcb lists
 0(0) DEBUG: tm_shutdown : done
 0(5050) shm_mem_destroy
 0(5050) destroying the shared memory lock
-----------------------------------------------------------------------------------------------------------
Please tell me what's wrong. And please tell me whether if my configuration on ser.cfg is right or wrong because I doubt it.
Thanx before...

Regards,
Meidiana



Have a burning question? Go to Yahoo! Answers and get answers from real people who know.